MDEV-33798: Follow-up patch
Don't deadlock kill event groups in other domains if they are not SPECULATE_OPTIMISTIC. Such event groups may not be able to safely roll back and retry (eg. DDL). But do deadlock kill a transaction T2 from a blocked transaction U in another domain, even if T2 has lower sub_id than U. Otherwise, in case of a cycle T2->T1->U->T2, we might not break the cycle if U is not SPECULATE_OPTIMISTIC Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
parent
596921dab8
commit
2a2019e199
@ -5400,31 +5400,32 @@ thd_rpl_deadlock_check(MYSQL_THD thd, MYSQL_THD other_thd)
|
|||||||
return 0;
|
return 0;
|
||||||
if (!rgi->is_parallel_exec)
|
if (!rgi->is_parallel_exec)
|
||||||
return 0;
|
return 0;
|
||||||
if (rgi->rli == other_rgi->rli)
|
if (rgi->rli == other_rgi->rli &&
|
||||||
|
rgi->current_gtid.domain_id == other_rgi->current_gtid.domain_id)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Within the same master connection, we can compare transaction order on
|
Within the same master connection and domain, we can compare transaction
|
||||||
the GTID sub_id, and rollback the later transaction to allow the earlier
|
order on the GTID sub_id, and rollback the later transaction to allow the
|
||||||
transaction to commit first.
|
earlier transaction to commit first.
|
||||||
*/
|
*/
|
||||||
if (!rgi->gtid_sub_id || !other_rgi->gtid_sub_id)
|
if (!rgi->gtid_sub_id || !other_rgi->gtid_sub_id ||
|
||||||
return 0;
|
rgi->gtid_sub_id > other_rgi->gtid_sub_id)
|
||||||
if (rgi->gtid_sub_id > other_rgi->gtid_sub_id)
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Lock conflicts between different master connection should usually not
|
Lock conflicts between different master connections or domains should
|
||||||
occur, but could still happen if user is running some special setup that
|
usually not occur, but could still happen if user is running some
|
||||||
tolerates conflicting updates (or in case of user error). We do not have a
|
special setup that tolerates conflicting updates (or in case of user
|
||||||
pre-defined ordering of transactions in this case, but we still need to
|
error). We do not have a pre-defined ordering of transactions in this
|
||||||
handle conflicts in _some_ way to avoid undetected deadlocks and hangs.
|
case, but we still need to handle conflicts in _some_ way to avoid
|
||||||
|
undetected deadlocks and hangs.
|
||||||
|
|
||||||
We do this by rolling back and retrying any transaction that is being
|
We do this by rolling back and retrying any transaction that is being
|
||||||
_optimistically_ applied. This can be overly conservative in some cases,
|
_optimistically_ applied. This can be overly conservative in some cases,
|
||||||
but should be fine as conflicts between different master connections are
|
but should be fine as conflicts between different master connections /
|
||||||
not expected to be common. And it ensures that we won't end up in a
|
domains are not common. And it ensures that we won't end up in a
|
||||||
deadlock and hang due to a transaction doing wait_for_prior_commit while
|
deadlock and hang due to a transaction doing wait_for_prior_commit while
|
||||||
holding locks that block something in another master connection.
|
holding locks that block something in another master connection.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user