
Hi Jimmy, Brandon, Sanja, Serg, Kristian Nielsen via developers <developers@lists.mariadb.org> writes:
Ensure that a pending semi-sync transaction can only be signalled on its THD while it is waiting in commit_trx(); not if the wait in commit_trx() is skipped for some reason.
Just a heads-up about when this MDEV-36934 needs to be merged up with MDEV-18983 in the current preview. As Brandon pointed out, there is a conflict between the two patches. The MDEV-36934 patch modifies the function is_thd_waiter(), which is deleted in MDEV-18983. When merging, just keep the is_thd_waiter() function deleted, and instead in Repl_semi_sync_master::commit_trx(), add a call to m_active_tranxs->get_tranx_node() to get the Tranx_node entry pointer outside the loop, as shown in the below diff. Hope this helps, - Kristian. ----------------------------------------------------------------------- diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc index 2a8a727e588..1885cada1ac 100644 --- a/sql/semisync_master.cc +++ b/sql/semisync_master.cc @@ -845,10 +854,15 @@ int Repl_semi_sync_master::commit_trx(const char *trx_wait_binlog_name, my_off_t trx_wait_binlog_pos) { bool success= 0; + Tranx_node *entry; DBUG_ENTER("Repl_semi_sync_master::commit_trx"); if (is_no_slave()) { + lock(); + m_active_tranxs->unlink_thd_as_waiter(trx_wait_binlog_name, + trx_wait_binlog_pos); + unlock(); rpl_semi_sync_master_no_transactions++; DBUG_RETURN(0); } @@ -875,6 +889,19 @@ int Repl_semi_sync_master::commit_trx(const char *trx_wait_binlog_name, if (!get_master_enabled() || !is_on()) goto l_end; + /* + Mark that our THD is now valid for signalling to by the ack thread. + It is important to ensure that we can never leave a no longer valid + THD in the transaction list and signal it, eg. MDEV-36934. This way, + we ensure the THD will only be signalled while this function is + running, even in case of some incorrect error handling or similar + that might leave a dangling THD in the list. + */ + entry= m_active_tranxs->get_tranx_node(trx_wait_binlog_name, + trx_wait_binlog_pos); + if (entry) + entry->thd_valid= true; + DBUG_PRINT("semisync", ("%s: wait pos (%s, %lu), repl(%d)", "Repl_semi_sync_master::commit_trx", trx_wait_binlog_name, (ulong)trx_wait_binlog_pos,