mirror of
https://github.com/MariaDB/server.git
synced 2025-02-05 13:22:17 +01:00
ddd7d5d8e3
Under unknown circumstances, the SQL layer may wrongly disregard an invocation of thd_mark_transaction_to_rollback() when an InnoDB transaction had been aborted (rolled back) due to one of the following errors: * HA_ERR_LOCK_DEADLOCK * HA_ERR_RECORD_CHANGED (if innodb_snapshot_isolation=ON) * HA_ERR_LOCK_WAIT_TIMEOUT (if innodb_rollback_on_timeout=ON) Such an error used to cause a crash of InnoDB during transaction commit. These changes aim to catch and report the error earlier, so that not only this crash can be avoided but also the original root cause be found and fixed more easily later. The idea of this fix is from Michael 'Monty' Widenius. HA_ERR_ROLLBACK: A new error code that will be translated into ER_ROLLBACK_ONLY, signalling that the current transaction has been aborted and the only allowed action is ROLLBACK. trx_t::state: Add TRX_STATE_ABORTED that is like TRX_STATE_NOT_STARTED, but noting that the transaction had been rolled back and aborted. trx_t::is_started(): Replaces trx_is_started(). ha_innobase: Check the transaction state in various places. Simplify the logic around SAVEPOINT. ha_innobase::is_valid_trx(): Replaces ha_innobase::is_read_only(). The InnoDB logic around transaction savepoints, commit, and rollback was unnecessarily complex and might have contributed to this inconsistency. So, we are simplifying that logic as well. trx_savept_t: Replace with const undo_no_t*. When we rollback to a savepoint, all we need to know is the number of undo log records that must survive. trx_named_savept_t, DB_NO_SAVEPOINT: Remove. We can store undo_no_t directly in the space allocated at innobase_hton->savepoint_offset. fts_trx_create(): Do not copy previous savepoints. fts_savepoint_rollback(): If a savepoint was not found, roll back everything after the default savepoint of fts_trx_create(). The test innodb_fts.savepoint is extended to cover this code. Reviewed by: Vladislav Lesin Tested by: Matthias Leich
96 lines
3.6 KiB
C
96 lines
3.6 KiB
C
/*****************************************************************************
|
|
|
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
|
Copyright (c) 2015, 2021, MariaDB Corporation.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file include/trx0roll.h
|
|
Transaction rollback
|
|
|
|
Created 3/26/1996 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#ifndef trx0roll_h
|
|
#define trx0roll_h
|
|
|
|
#include "trx0trx.h"
|
|
#include "mtr0mtr.h"
|
|
#include "trx0sys.h"
|
|
|
|
extern bool trx_rollback_is_active;
|
|
extern const trx_t* trx_roll_crash_recv_trx;
|
|
|
|
/** Report progress when rolling back a row of a recovered transaction. */
|
|
void trx_roll_report_progress();
|
|
/*******************************************************************//**
|
|
Rollback or clean up any incomplete transactions which were
|
|
encountered in crash recovery. If the transaction already was
|
|
committed, then we clean up a possible insert undo log. If the
|
|
transaction was not yet committed, then we roll it back.
|
|
@param all true=roll back all recovered active transactions;
|
|
false=roll back any incomplete dictionary transaction */
|
|
void
|
|
trx_rollback_recovered(bool all);
|
|
/*******************************************************************//**
|
|
Rollback or clean up any incomplete transactions which were
|
|
encountered in crash recovery. If the transaction already was
|
|
committed, then we clean up a possible insert undo log. If the
|
|
transaction was not yet committed, then we roll it back.
|
|
Note: this is done in a background thread. */
|
|
void trx_rollback_all_recovered(void*);
|
|
/*********************************************************************//**
|
|
Creates a rollback command node struct.
|
|
@return own: rollback node struct */
|
|
roll_node_t*
|
|
roll_node_create(
|
|
/*=============*/
|
|
mem_heap_t* heap); /*!< in: mem heap where created */
|
|
/***********************************************************//**
|
|
Performs an execution step for a rollback command node in a query graph.
|
|
@return query thread to run next, or NULL */
|
|
que_thr_t*
|
|
trx_rollback_step(
|
|
/*==============*/
|
|
que_thr_t* thr); /*!< in: query thread */
|
|
/*******************************************************************//**
|
|
Rollback a transaction used in MySQL.
|
|
@return error code or DB_SUCCESS */
|
|
dberr_t
|
|
trx_rollback_for_mysql(
|
|
/*===================*/
|
|
trx_t* trx) /*!< in/out: transaction */
|
|
MY_ATTRIBUTE((nonnull));
|
|
|
|
/** Rollback node states */
|
|
enum roll_node_state {
|
|
ROLL_NODE_NONE = 0, /*!< Unknown state */
|
|
ROLL_NODE_SEND, /*!< about to send a rollback signal to
|
|
the transaction */
|
|
ROLL_NODE_WAIT /*!< rollback signal sent to the
|
|
transaction, waiting for completion */
|
|
};
|
|
|
|
/** Rollback command node in a query graph */
|
|
struct roll_node_t{
|
|
que_common_t common; /*!< node type: QUE_NODE_ROLLBACK */
|
|
enum roll_node_state state; /*!< node execution state */
|
|
undo_no_t savept; /*!< savepoint to which to
|
|
roll back; 0=entire transaction */
|
|
que_thr_t* undo_thr;/*!< undo query graph */
|
|
};
|
|
|
|
#endif
|