MDEV 15532 Assertion `!log->same_pk' failed in row_log_table_apply_delete

The reason for the failure is that
thd->mdl_context.release_transactional_locks()
was called after commit & rollback even in cases where the current
transaction is still active.

For 10.2, 10.3 and 10.4 the fix is simple:
- Replace all calls to thd->mdl_context.release_transactional_locks() with
  thd->release_transactional_locks(). The thd function will only call
  the mdl_context function if there are no active transactional locks.
  In 10.6 we will better fix where we will change the return value for
  some trans_xxx() functions to indicate if transaction did close the
  transaction or not. This will avoid the need of the indirect call.

Other things:
- trans_xa_commit() and trans_xa_rollback() will automatically
  call release_transactional_locks() if the transaction is closed.
- We can't do that for the other functions as the caller of many of these
  are doing additional work (like close_thread_tables) before calling
  release_transactional_locks().
- Added missing abort_result_set() and missing DBUG_RETURN in
  select_create::send_eof()
- Fixed wrong indentation in injector::transaction::commit()
This commit is contained in:
Monty 2020-11-30 15:29:32 +02:00
parent 37352c4b55
commit 828471cbf8
21 changed files with 163 additions and 83 deletions

View file

@ -241,7 +241,7 @@ DROP TABLE t1;
#
# Bug#12352846 - TRANS_XA_START(THD*):
# ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
# FAILED
# FAILED
#
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
@ -291,3 +291,29 @@ connection default;
XA END 'xid1';
XA ROLLBACK 'xid1';
DROP TABLE t1, t2, t3;
#
# MDEV 15532 XA: Assertion `!log->same_pk' failed in
# row_log_table_apply_delete
#
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1),(2);
connect con1,localhost,root,,test;
XA START 'xid';
UPDATE t1 SET a = 5;
connection default;
SET innodb_lock_wait_timeout= 2, lock_wait_timeout= 2;
ALTER TABLE non_existing_table1;
ERROR 42S02: Table 'test.non_existing_table1' doesn't exist
ALTER TABLE t1 FORCE;;
connection con1;
ALTER TABLE non_existing_table2;
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
DELETE FROM t1 LIMIT 1;
connection default;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
connection con1;
XA END 'xid';
XA ROLLBACK 'xid';
DROP TABLE t1;
disconnect con1;
connection default;

View file

@ -413,6 +413,7 @@ CREATE TABLE x AS SELECT * FROM t1;
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
connect con1,localhost,root,,test;
SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 1;
SET lock_wait_timeout=5;
ALTER TABLE t1 ADD FOREIGN KEY f (a) REFERENCES t1 (pk), LOCK=EXCLUSIVE;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
disconnect con1;

View file

@ -414,6 +414,7 @@ INSERT INTO t1 VALUES (1,2);
CREATE TABLE x AS SELECT * FROM t1;
--connect (con1,localhost,root,,test)
SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 1;
SET lock_wait_timeout=5;
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE t1 ADD FOREIGN KEY f (a) REFERENCES t1 (pk), LOCK=EXCLUSIVE;# Cleanup
--disconnect con1

View file

@ -342,7 +342,7 @@ DROP TABLE t1;
--echo #
--echo # Bug#12352846 - TRANS_XA_START(THD*):
--echo # ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL()
--echo # FAILED
--echo # FAILED
--echo #
--disable_warnings
@ -401,7 +401,7 @@ CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t2 (pk INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2);
CREATE TABLE t3 (i INT) ENGINE=InnoDB;
XA BEGIN 'xid1';
REPLACE INTO t1 SELECT * FROM t2;
@ -430,5 +430,43 @@ XA END 'xid1';
XA ROLLBACK 'xid1';
DROP TABLE t1, t2, t3;
--source include/wait_until_count_sessions.inc
--echo #
--echo # MDEV 15532 XA: Assertion `!log->same_pk' failed in
--echo # row_log_table_apply_delete
--echo #
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1),(2);
--connect (con1,localhost,root,,test)
XA START 'xid';
UPDATE t1 SET a = 5;
--connection default
SET innodb_lock_wait_timeout= 2, lock_wait_timeout= 2;
--error ER_NO_SUCH_TABLE
ALTER TABLE non_existing_table1;
--send ALTER TABLE t1 FORCE;
--connection con1
--error ER_XAER_RMFAIL
ALTER TABLE non_existing_table2;
DELETE FROM t1 LIMIT 1;
--connection default
--error ER_LOCK_WAIT_TIMEOUT
--reap
# Cleanup
--connection con1
XA END 'xid';
XA ROLLBACK 'xid';
DROP TABLE t1;
--disconnect con1
connection default;
--source include/wait_until_count_sessions.inc

View file

@ -7150,10 +7150,10 @@ error:
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();
@ -8554,7 +8554,7 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi)
"COMMIT /* implicit, from Xid_log_event */");
thd->variables.option_bits&= ~OPTION_GTID_BEGIN;
res= trans_commit(thd); /* Automatically rolls back on error. */
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
#ifdef WITH_WSREP
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);

View file

@ -2842,6 +2842,9 @@ void MDL_context::rollback_to_savepoint(const MDL_savepoint &mdl_savepoint)
void MDL_context::release_transactional_locks()
{
DBUG_ENTER("MDL_context::release_transactional_locks");
/* Fail if there are active transactions */
DBUG_ASSERT(!(current_thd->server_status &
(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY)));
release_locks_stored_before(MDL_STATEMENT, NULL);
release_locks_stored_before(MDL_TRANSACTION, NULL);
DBUG_VOID_RETURN;

View file

@ -432,7 +432,7 @@ rpl_slave_state::truncate_state_table(THD *thd)
close_thread_tables(thd);
ha_commit_trans(thd, TRUE);
}
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
reenable_binlog(thd);
@ -726,7 +726,7 @@ end:
}
else
{
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
#ifdef HAVE_REPLICATION
rpl_group_info::pending_gtid_deletes_free(elist);
#endif

View file

@ -68,34 +68,34 @@ injector::transaction::~transaction()
*/
int injector::transaction::commit()
{
DBUG_ENTER("injector::transaction::commit()");
int error= m_thd->binlog_flush_pending_rows_event(true);
/*
Cluster replication does not preserve statement or
transaction boundaries of the master. Instead, a new
transaction on replication slave is started when a new GCI
(global checkpoint identifier) is issued, and is committed
when the last event of the check point has been received and
processed. This ensures consistency of each cluster in
cluster replication, and there is no requirement for stronger
consistency: MySQL replication is asynchronous with other
engines as well.
DBUG_ENTER("injector::transaction::commit()");
int error= m_thd->binlog_flush_pending_rows_event(true);
/*
Cluster replication does not preserve statement or
transaction boundaries of the master. Instead, a new
transaction on replication slave is started when a new GCI
(global checkpoint identifier) is issued, and is committed
when the last event of the check point has been received and
processed. This ensures consistency of each cluster in
cluster replication, and there is no requirement for stronger
consistency: MySQL replication is asynchronous with other
engines as well.
A practical consequence of that is that row level replication
stream passed through the injector thread never contains
COMMIT events.
Here we should preserve the server invariant that there is no
outstanding statement transaction when the normal transaction
is committed by committing the statement transaction
explicitly.
*/
trans_commit_stmt(m_thd);
if (!trans_commit(m_thd))
{
close_thread_tables(m_thd);
m_thd->mdl_context.release_transactional_locks();
}
DBUG_RETURN(error);
A practical consequence of that is that row level replication
stream passed through the injector thread never contains
COMMIT events.
Here we should preserve the server invariant that there is no
outstanding statement transaction when the normal transaction
is committed by committing the statement transaction
explicitly.
*/
trans_commit_stmt(m_thd);
if (!trans_commit(m_thd))
{
close_thread_tables(m_thd);
m_thd->release_transactional_locks();
}
DBUG_RETURN(error);
}

View file

@ -1736,7 +1736,7 @@ end:
if (table_opened)
{
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
if (array_inited)
delete_dynamic(&array);
@ -1904,7 +1904,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error)
if (error)
{
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
if (thd == rli->sql_driver_thd)
{
@ -2018,10 +2018,10 @@ void rpl_group_info::slave_close_thread_tables(THD *thd)
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();

View file

@ -2163,10 +2163,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();
}
@ -3119,10 +3119,10 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();
}

View file

@ -42,7 +42,7 @@ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
trans_rollback_stmt(thd);
trans_rollback(thd);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
/*
table_list->table has been closed and freed. Do not reference
@ -115,7 +115,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
acquire the exclusive lock to satisfy MDL asserts and avoid
deadlocks.
*/
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
/*
Attempt to do full-blown table open in mysql_admin_table() has failed.
Let us try to open at least a .FRM for this table.
@ -266,7 +266,7 @@ end:
}
/* In case of a temporary table there will be no metadata lock. */
if (error && has_mdl_lock)
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
DBUG_RETURN(error);
}
@ -543,7 +543,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
trans_rollback(thd);
close_thread_tables(thd);
table->table= NULL;
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
MDL_SHARED_NO_READ_WRITE, MDL_TRANSACTION);
}
@ -597,7 +597,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
trans_rollback_stmt(thd);
trans_rollback(thd);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
DBUG_PRINT("admin", ("simple error, admin next table"));
continue;
case -1: // error, message could be written to net
@ -670,7 +670,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
trans_commit_stmt(thd);
trans_commit(thd);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
lex->reset_query_tables_list(FALSE);
/*
Restore Query_tables_list::sql_command value to make statement
@ -803,7 +803,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
thd->open_options|= extra_open_options;
close_thread_tables(thd);
table->table= NULL;
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
table->mdl_request.init(MDL_key::TABLE, table->db, table->table_name,
MDL_SHARED_NO_READ_WRITE, MDL_TRANSACTION);
table->mdl_request.set_type(MDL_SHARED_READ);
@ -1035,7 +1035,7 @@ send_result_message:
trans_commit_stmt(thd);
trans_commit(thd);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
/* Clear references to TABLE and MDL_ticket after releasing them. */
table->mdl_request.ticket= NULL;
@ -1188,7 +1188,7 @@ send_result_message:
goto err;
}
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
/*
If it is CHECK TABLE v1, v2, v3, and v1, v2, v3 are views, we will run
@ -1226,7 +1226,7 @@ err:
table->table= 0;
}
close_thread_tables(thd); // Shouldn't be needed
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
thd->resume_subsequent_commits(suspended_wfc);
DBUG_RETURN(TRUE);
}

View file

@ -8652,7 +8652,7 @@ close_mysql_tables(THD *thd)
if (! thd->in_sub_stmt)
trans_commit_stmt(thd);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
/*

View file

@ -4485,7 +4485,7 @@ void destroy_thd(MYSQL_THD thd)
void reset_thd(MYSQL_THD thd)
{
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
thd->free_items();
free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
}

View file

@ -4177,6 +4177,13 @@ public:
locked_tables_mode= mode_arg;
}
void leave_locked_tables_mode();
/* Relesae transactional locks if there are no active transactions */
void release_transactional_locks()
{
if (!(server_status &
(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY)))
mdl_context.release_transactional_locks();
}
int decide_logging_format(TABLE_LIST *tables);
/*
In Some cases when decide_logging_format is called it does not have all

View file

@ -2948,7 +2948,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
if (thd->mdl_context.clone_ticket(&di->grl_protection) ||
thd->mdl_context.clone_ticket(&di->table_list.mdl_request))
{
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
di->handler_thread_initialized= TRUE;
goto err;
}
@ -3144,7 +3144,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
mysql_mutex_unlock(&thd->LOCK_thd_data);
close_thread_tables(thd); // Free the table
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
mysql_cond_broadcast(&di->cond_client); // Safety
mysql_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table
@ -4580,7 +4580,8 @@ bool select_create::send_eof()
WSREP_ERROR("Appending table key for CTAS failed: %s, %d",
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void", rcode);
return true;
abort_result_set();
DBUG_RETURN(true);
}
/* If commit fails, we should be able to reset the OK status. */
thd->get_stmt_da()->set_overwrite_status(TRUE);

View file

@ -2034,7 +2034,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
locks.
*/
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
thd->cleanup_after_query();
@ -2099,7 +2099,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ulonglong options= (ulonglong) (uchar) packet[0];
if (trans_commit_implicit(thd))
break;
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
if (check_global_access(thd,RELOAD_ACL))
break;
general_log_print(thd, command, NullS);
@ -2132,7 +2132,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (trans_commit_implicit(thd))
break;
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
my_ok(thd);
break;
}
@ -2934,7 +2934,7 @@ err:
/* Close tables and release metadata locks. */
close_thread_tables(thd);
DBUG_ASSERT(!thd->locked_tables_mode);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
return TRUE;
}
@ -3406,7 +3406,7 @@ mysql_execute_command(THD *thd)
/* Commit the normal transaction if one is active. */
bool commit_failed= trans_commit_implicit(thd);
/* Release metadata locks acquired in this transaction. */
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
if (commit_failed)
{
WSREP_DEBUG("implicit commit failed, MDL released: %lld",
@ -4645,7 +4645,7 @@ mysql_execute_command(THD *thd)
{
res= trans_commit_implicit(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
}
if (thd->global_read_lock.is_acquired())
@ -4659,7 +4659,7 @@ mysql_execute_command(THD *thd)
res= trans_commit_implicit(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
if (res)
goto error;
@ -5313,7 +5313,7 @@ mysql_execute_command(THD *thd)
DBUG_PRINT("info", ("Executing SQLCOM_BEGIN thd: %p", thd));
if (trans_begin(thd, lex->start_transaction_opt))
{
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
WSREP_DEBUG("BEGIN failed, MDL released: %lld",
(longlong) thd->thread_id);
goto error;
@ -5331,7 +5331,7 @@ mysql_execute_command(THD *thd)
(thd->variables.completion_type == 2 &&
lex->tx_release != TVL_NO));
bool commit_failed= trans_commit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
if (commit_failed)
{
WSREP_DEBUG("COMMIT failed, MDL released: %lld",
@ -5382,7 +5382,7 @@ mysql_execute_command(THD *thd)
(thd->variables.completion_type == 2 &&
lex->tx_release != TVL_NO));
bool rollback_failed= trans_rollback(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
if (rollback_failed)
{
@ -5859,7 +5859,6 @@ mysql_execute_command(THD *thd)
case SQLCOM_XA_COMMIT:
{
bool commit_failed= trans_xa_commit(thd);
thd->mdl_context.release_transactional_locks();
if (commit_failed)
{
WSREP_DEBUG("XA commit failed, MDL released: %lld",
@ -5877,7 +5876,6 @@ mysql_execute_command(THD *thd)
case SQLCOM_XA_ROLLBACK:
{
bool rollback_failed= trans_xa_rollback(thd);
thd->mdl_context.release_transactional_locks();
if (rollback_failed)
{
WSREP_DEBUG("XA rollback failed, MDL released: %lld",
@ -6095,7 +6093,7 @@ finish:
all storage engines including binary log.
*/
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
else if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END))
{
@ -6108,7 +6106,7 @@ finish:
/* Commit the normal transaction if one is active. */
trans_commit_implicit(thd);
thd->get_stmt_da()->set_overwrite_status(false);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
}
else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
@ -6123,7 +6121,7 @@ finish:
- If in autocommit mode, or outside a transactional context,
automatically release metadata locks of the current statement.
*/
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
else if (! thd->in_sub_stmt)
{
@ -6145,7 +6143,7 @@ finish:
{
WSREP_DEBUG("Forcing release of transactional locks for thd: %lld",
(longlong) thd->thread_id);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
#endif /* WITH_WSREP */

View file

@ -4278,7 +4278,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
}
/* Preserve CHANGE MASTER attributes */

View file

@ -3730,7 +3730,7 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type)
if (trans_commit_stmt(thd) || trans_commit(thd))
{
thd->variables.option_bits&= ~OPTION_AUTOCOMMIT;
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
WSREP_DEBUG("autocommit, MDL TRX lock released: %lld",
(longlong) thd->thread_id);
return true;

View file

@ -212,7 +212,7 @@ bool trans_begin(THD *thd, uint flags)
Release transactional metadata locks only after the
transaction has been committed.
*/
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
// The RO/RW options are mutually exclusive.
DBUG_ASSERT(!((flags & MYSQL_START_TRANS_OPT_READ_ONLY) &&
@ -889,11 +889,13 @@ bool trans_xa_prepare(THD *thd)
/**
Commit and terminate the a XA transaction.
Transactional locks are released if transaction ended
@param thd Current thread
@retval FALSE Success
@retval TRUE Failure
*/
bool trans_xa_commit(THD *thd)
@ -984,6 +986,7 @@ bool trans_xa_commit(THD *thd)
thd->transaction.xid_state.xa_state= XA_NOTR;
trans_track_end_trx(thd);
thd->mdl_context.release_transactional_locks();
DBUG_RETURN(res);
}
@ -991,6 +994,7 @@ bool trans_xa_commit(THD *thd)
/**
Roll back and terminate a XA transaction.
Transactional locks are released if transaction ended
@param thd Current thread
@ -1041,6 +1045,7 @@ bool trans_xa_rollback(THD *thd)
thd->transaction.xid_state.xa_state= XA_NOTR;
trans_track_end_trx(thd);
thd->mdl_context.release_transactional_locks();
DBUG_RETURN(res);
}

View file

@ -187,7 +187,7 @@ static wsrep_cb_status_t wsrep_apply_events(THD* thd,
trans_rollback(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
thd->wsrep_conflict_state= NO_CONFLICT;
DBUG_RETURN(WSREP_CB_FAILURE);
}
@ -369,7 +369,7 @@ wsrep_cb_status_t wsrep_commit_cb(void* const ctx,
/* Cleanup */
wsrep_set_apply_format(thd, NULL);
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
thd->reset_query(); /* Mutex protected */
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;

View file

@ -75,7 +75,7 @@ void wsrep_client_rollback(THD *thd)
}
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
/* release explicit MDL locks */
thd->mdl_context.release_explicit_locks();
@ -211,7 +211,7 @@ void wsrep_replay_sp_transaction(THD* thd)
thd->locked_tables_list.unlock_locked_tables(thd);
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
}
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
mysql_mutex_unlock(&thd->LOCK_thd_data);
THD *replay_thd= new THD(true);
@ -350,7 +350,7 @@ void wsrep_replay_transaction(THD *thd)
thd->locked_tables_list.unlock_locked_tables(thd);
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
}
thd->mdl_context.release_transactional_locks();
thd->release_transactional_locks();
/*
Replaying will call MYSQL_START_STATEMENT when handling
BEGIN Query_log_event so end statement must be called before