mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-31448: Killing a replica thread awaiting its GCO can hang/crash a parallel replica
The problem was an incorrect unmark_start_commit() in signal_error_to_sql_driver_thread(). If an event group gets an error, this unmark could run after the following GCO started, and the subsequent re-marking could access de-allocated GCO. The offending unmark_start_commit() looks obviously incorrect, and the fix is to just remove it. It was introduced in the MDEV-8302 patch, the commit message of which suggests it was added there solely to satisfy an assertion in ha_rollback_trans(). So update this assertion instead to not trigger for event groups that experienced an error (rgi->worker_error). When an error occurs in an event group, all following event groups are skipped anyway, so the unmark should never be needed in this case. Reviewed-by: Andrei Elkin <andrei.elkin@mariadb.com> Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
@ -1898,13 +1898,22 @@ int ha_rollback_trans(THD *thd, bool all)
|
||||
attempt. Otherwise those following transactions can run too early, and
|
||||
possibly cause replication to fail. See comments in retry_event_group().
|
||||
|
||||
(This concerns rollbacks due to temporary errors where the transaction
|
||||
will be retried afterwards. For non-recoverable errors, following
|
||||
transactions will not start but just be skipped as the worker threads
|
||||
perform the error stop).
|
||||
|
||||
There were several bugs with this in the past that were very hard to
|
||||
track down (MDEV-7458, MDEV-8302). So we add here an assertion for
|
||||
rollback without signalling following transactions. And in release
|
||||
builds, we explicitly do the signalling before rolling back.
|
||||
*/
|
||||
DBUG_ASSERT(!(thd->rgi_slave && thd->rgi_slave->did_mark_start_commit));
|
||||
if (thd->rgi_slave && thd->rgi_slave->did_mark_start_commit)
|
||||
DBUG_ASSERT( !(thd->rgi_slave &&
|
||||
!thd->rgi_slave->worker_error &&
|
||||
thd->rgi_slave->did_mark_start_commit));
|
||||
if (thd->rgi_slave &&
|
||||
!thd->rgi_slave->worker_error &&
|
||||
thd->rgi_slave->did_mark_start_commit)
|
||||
thd->rgi_slave->unmark_start_commit();
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user