mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-31655: Parallel replication deadlock victim preference code errorneously removed
Restore code to make InnoDB choose the second transaction as a deadlock victim if two transactions deadlock that need to commit in-order for parallel replication. This code was erroneously removed when VATS was implemented in InnoDB. Also add a test case for InnoDB choosing the right deadlock victim. Also fixes this bug, with testcase that reliably reproduces: MDEV-28776: rpl.rpl_mark_optimize_tbl_ddl fails with timeout on sync_with_master Note: This should be null-merged to 10.6, as a different fix is needed there due to InnoDB locking code changes. Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
@ -5272,6 +5272,49 @@ thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other_thd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If the storage engine detects a deadlock, and needs to choose a victim
|
||||
transaction to roll back, it can call this function to ask the upper
|
||||
server layer for which of two possible transactions is prefered to be
|
||||
aborted and rolled back.
|
||||
|
||||
In parallel replication, if two transactions are running in parallel and
|
||||
one is fixed to commit before the other, then the one that commits later
|
||||
will be prefered as the victim - chosing the early transaction as a victim
|
||||
will not resolve the deadlock anyway, as the later transaction still needs
|
||||
to wait for the earlier to commit.
|
||||
|
||||
The return value is -1 if the first transaction is prefered as a deadlock
|
||||
victim, 1 if the second transaction is prefered, or 0 for no preference (in
|
||||
which case the storage engine can make the choice as it prefers).
|
||||
*/
|
||||
extern "C" int
|
||||
thd_deadlock_victim_preference(const MYSQL_THD thd1, const MYSQL_THD thd2)
|
||||
{
|
||||
rpl_group_info *rgi1, *rgi2;
|
||||
|
||||
if (!thd1 || !thd2)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
If the transactions are participating in the same replication domain in
|
||||
parallel replication, then request to select the one that will commit
|
||||
later (in the fixed commit order from the master) as the deadlock victim.
|
||||
*/
|
||||
rgi1= thd1->rgi_slave;
|
||||
rgi2= thd2->rgi_slave;
|
||||
if (rgi1 && rgi2 &&
|
||||
rgi1->is_parallel_exec &&
|
||||
rgi1->rli == rgi2->rli &&
|
||||
rgi1->current_gtid.domain_id == rgi2->current_gtid.domain_id)
|
||||
return rgi1->gtid_sub_id < rgi2->gtid_sub_id ? 1 : -1;
|
||||
|
||||
/* No preferences, let the storage engine decide. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
|
||||
{
|
||||
return(thd->transaction.all.modified_non_trans_table);
|
||||
|
Reference in New Issue
Block a user