diff options
author | Kristian Nielsen <knielsen@knielsen-hq.org> | 2015-01-07 14:45:39 +0100 |
---|---|---|
committer | Kristian Nielsen <knielsen@knielsen-hq.org> | 2015-01-07 14:45:39 +0100 |
commit | f27817c1d0e6d81392470e9086624e88ae08b11f (patch) | |
tree | 07143fafd819462ef1baf0d451d5537f1a60610b /sql/rpl_rli.h | |
parent | 4a3251595cc697bfdb15b67c07514bd3c4779e37 (diff) | |
download | mariadb-git-f27817c1d0e6d81392470e9086624e88ae08b11f.tar.gz |
MDEV-7326: Server deadlock in connection with parallel replication
The bug occurs when a transaction does a retry after all transactions have
done mark_start_commit() in a batch of group commit from the master. In this
case, the retrying transaction can unmark_start_commit() after the following
batch has already started running and de-allocated the GCO. Then after retry,
the transaction will re-do mark_start_commit() on a de-allocated GCO, and also
wakeup of later GCOs can be lost.
This was seen "in the wild" by a user, even though it is not known exactly
what circumstances can lead to retry of one transaction after all transactions
in a group have reached the commit phase.
The lifetime around GCO was somewhat clunky anyway. With this patch, a GCO
lives until rpl_parallel_entry::last_committed_sub_id has reached the last
transaction in the GCO. This guarantees that the GCO will still be alive when
a transaction does mark_start_commit(). Also, we now loop over the list of
active GCOs for wakeup, to ensure we do not lose a wakeup even in the
problematic case.
Diffstat (limited to 'sql/rpl_rli.h')
-rw-r--r-- | sql/rpl_rli.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 9885417aa3f..fb4e3261468 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -563,6 +563,10 @@ struct rpl_group_info (When we execute in parallel the transactions that group committed together on the master, we still need to wait for any prior transactions to have reached the commit stage). + + The pointed-to gco is only valid for as long as + gtid_sub_id < parallel_entry->last_committed_sub_id. After that, it can + be freed by another thread. */ group_commit_orderer *gco; |