mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-7335: Potential parallel slave deadlock with specific binlog corruption
If somehow the COMMIT or XID event in an event group was missing, the code in parallel replication to handle this was not sufficient, leading to server deadlock.
This commit is contained in:
@@ -640,7 +640,7 @@ handle_rpl_parallel_thread(void *arg)
|
||||
}
|
||||
DBUG_ASSERT(qev->typ==rpl_parallel_thread::queued_event::QUEUED_EVENT);
|
||||
|
||||
thd->rgi_slave= group_rgi= rgi;
|
||||
thd->rgi_slave= rgi;
|
||||
gco= rgi->gco;
|
||||
/* Handle a new event group, which will be initiated by a GTID event. */
|
||||
if ((event_type= qev->ev->get_type_code()) == GTID_EVENT)
|
||||
@@ -657,6 +657,21 @@ handle_rpl_parallel_thread(void *arg)
|
||||
}
|
||||
});
|
||||
|
||||
if(unlikely(thd->wait_for_commit_ptr) && group_rgi != NULL)
|
||||
{
|
||||
/*
|
||||
This indicates that we get a new GTID event in the middle of
|
||||
a not completed event group. This is corrupt binlog (the master
|
||||
will never write such binlog), so it does not happen unless
|
||||
someone tries to inject wrong crafted binlog, but let us still
|
||||
try to handle it somewhat nicely.
|
||||
*/
|
||||
group_rgi->cleanup_context(thd, true);
|
||||
finish_event_group(rpt, group_rgi->gtid_sub_id,
|
||||
group_rgi->parallel_entry, group_rgi);
|
||||
rpt->loc_free_rgi(group_rgi);
|
||||
}
|
||||
|
||||
in_event_group= true;
|
||||
/*
|
||||
If the standalone flag is set, then this event group consists of a
|
||||
@@ -742,19 +757,6 @@ handle_rpl_parallel_thread(void *arg)
|
||||
unlock_or_exit_cond(thd, &entry->LOCK_parallel_entry,
|
||||
&did_enter_cond, &old_stage);
|
||||
|
||||
if(thd->wait_for_commit_ptr)
|
||||
{
|
||||
/*
|
||||
This indicates that we get a new GTID event in the middle of
|
||||
a not completed event group. This is corrupt binlog (the master
|
||||
will never write such binlog), so it does not happen unless
|
||||
someone tries to inject wrong crafted binlog, but let us still
|
||||
try to handle it somewhat nicely.
|
||||
*/
|
||||
rgi->cleanup_context(thd, true);
|
||||
thd->wait_for_commit_ptr->unregister_wait_for_prior_commit();
|
||||
thd->wait_for_commit_ptr->wakeup_subsequent_commits(rgi->worker_error);
|
||||
}
|
||||
thd->wait_for_commit_ptr= &rgi->commit_orderer;
|
||||
|
||||
if (opt_gtid_ignore_duplicates)
|
||||
@@ -780,6 +782,7 @@ handle_rpl_parallel_thread(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
group_rgi= rgi;
|
||||
group_ending= is_group_ending(qev->ev, event_type);
|
||||
if (group_ending && likely(!rgi->worker_error))
|
||||
{
|
||||
|
Reference in New Issue
Block a user