mirror of
https://github.com/MariaDB/server.git
synced 2026-04-28 11:15:33 +02:00
MDEV-6718: Server crashed in Gtid_log_event::Gtid_log_event with parallel replication
The bug occured in parallel replication when re-trying transactions that failed due to deadlock. In this case, the relay log file is re-opened and the events are read out again. This reading requires a format description event of the appropriate version. But the code was using a description event stored in rli, which is not thread-safe. This could lead to various rare races if the format description event was replaced by the SQL driver thread at the exact moment where a worker thread was trying to use it. The fix is to instead make the retry code create and maintain its own format description event. When the relay log file is opened, we first read the format description event from the start of the file, before seeking to the current position. This now uses the same code as when the SQL driver threads starts from a given relay log position. This also makes sure that the correct format description event version will be used in cases where the version of the binlog could change during replication.
This commit is contained in:
parent
a98a034c5e
commit
8a3e2f29bb
3 changed files with 112 additions and 64 deletions
|
|
@ -290,6 +290,7 @@ retry_event_group(rpl_group_info *rgi, rpl_parallel_thread *rpt,
|
|||
THD *thd= rgi->thd;
|
||||
rpl_parallel_entry *entry= rgi->parallel_entry;
|
||||
ulong retries= 0;
|
||||
Format_description_log_event *description_event= NULL;
|
||||
|
||||
do_retry:
|
||||
event_count= 0;
|
||||
|
|
@ -355,6 +356,14 @@ do_retry:
|
|||
goto err;
|
||||
}
|
||||
cur_offset= rgi->retry_start_offset;
|
||||
delete description_event;
|
||||
description_event=
|
||||
read_relay_log_description_event(&rlog, cur_offset, &errmsg);
|
||||
if (!description_event)
|
||||
{
|
||||
err= 1;
|
||||
goto err;
|
||||
}
|
||||
my_b_seek(&rlog, cur_offset);
|
||||
|
||||
do
|
||||
|
|
@ -367,8 +376,7 @@ do_retry:
|
|||
for (;;)
|
||||
{
|
||||
old_offset= cur_offset;
|
||||
ev= Log_event::read_log_event(&rlog, 0,
|
||||
rli->relay_log.description_event_for_exec /* ToDo: this needs fixing */,
|
||||
ev= Log_event::read_log_event(&rlog, 0, description_event,
|
||||
opt_slave_sql_verify_checksum);
|
||||
cur_offset= my_b_tell(&rlog);
|
||||
|
||||
|
|
@ -416,7 +424,12 @@ do_retry:
|
|||
}
|
||||
|
||||
event_type= ev->get_type_code();
|
||||
if (!Log_event::is_group_event(event_type))
|
||||
if (event_type == FORMAT_DESCRIPTION_EVENT)
|
||||
{
|
||||
delete description_event;
|
||||
description_event= (Format_description_log_event *)ev;
|
||||
continue;
|
||||
} else if (!Log_event::is_group_event(event_type))
|
||||
{
|
||||
delete ev;
|
||||
continue;
|
||||
|
|
@ -472,6 +485,8 @@ do_retry:
|
|||
|
||||
err:
|
||||
|
||||
if (description_event)
|
||||
delete description_event;
|
||||
if (fd >= 0)
|
||||
{
|
||||
end_io_cache(&rlog);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue