diff --git a/mysql-test/suite/rpl/r/rpl_parallel.result b/mysql-test/suite/rpl/r/rpl_parallel.result index b04d9e7748e..fc4c3a3787e 100644 --- a/mysql-test/suite/rpl/r/rpl_parallel.result +++ b/mysql-test/suite/rpl/r/rpl_parallel.result @@ -706,6 +706,26 @@ SET GLOBAL binlog_format=@old_format; SET GLOBAL slave_parallel_threads=0; SET GLOBAL slave_parallel_threads=10; include/start_slave.inc +*** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** +include/stop_slave.inc +SET GLOBAL replicate_ignore_table="test.t3"; +SET GLOBAL slave_parallel_threads=2; +include/start_slave.inc +INSERT INTO t3 VALUES (100, rand()); +INSERT INTO t3 VALUES (101, rand()); +INSERT INTO t3 VALUES (102, rand()); +INSERT INTO t3 VALUES (103, rand()); +INSERT INTO t3 VALUES (104, rand()); +INSERT INTO t3 VALUES (105, rand()); +include/stop_slave.inc +SET GLOBAL replicate_ignore_table=""; +include/start_slave.inc +INSERT INTO t3 VALUES (106, rand()); +INSERT INTO t3 VALUES (107, rand()); +SELECT * FROM t3 WHERE a >= 100 ORDER BY a; +a b +106 # +107 # include/stop_slave.inc SET GLOBAL slave_parallel_threads=@old_parallel_threads; include/start_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_parallel.test b/mysql-test/suite/rpl/t/rpl_parallel.test index 0a064e7a227..a8884143c4d 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel.test +++ b/mysql-test/suite/rpl/t/rpl_parallel.test @@ -1069,6 +1069,47 @@ SET GLOBAL slave_parallel_threads=0; SET GLOBAL slave_parallel_threads=10; --source include/start_slave.inc +--echo *** MDEV-5788 Incorrect free of rgi->deferred_events in parallel replication *** + +--connection server_2 +# Use just two worker threads, so we are sure to get the rpl_group_info added +# to the free list, which is what triggered the bug. +--source include/stop_slave.inc +SET GLOBAL replicate_ignore_table="test.t3"; +SET GLOBAL slave_parallel_threads=2; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t3 VALUES (100, rand()); +INSERT INTO t3 VALUES (101, rand()); + +--save_master_pos + +--connection server_2 +--sync_with_master + +--connection server_1 +INSERT INTO t3 VALUES (102, rand()); +INSERT INTO t3 VALUES (103, rand()); +INSERT INTO t3 VALUES (104, rand()); +INSERT INTO t3 VALUES (105, rand()); + +--connection server_2 +--sync_with_master +--source include/stop_slave.inc +SET GLOBAL replicate_ignore_table=""; +--source include/start_slave.inc + +--connection server_1 +INSERT INTO t3 VALUES (106, rand()); +INSERT INTO t3 VALUES (107, rand()); +--save_master_pos + +--connection server_2 +--sync_with_master +--replace_column 2 # +SELECT * FROM t3 WHERE a >= 100 ORDER BY a; + --connection server_2 --source include/stop_slave.inc diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 154a95c1028..58b4948baae 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -789,9 +789,10 @@ rpl_parallel_thread::get_rgi(Relay_log_info *rli, Gtid_log_event *gtid_ev, return NULL; } rgi->is_parallel_exec = true; - if ((rgi->deferred_events_collecting= rli->mi->rpl_filter->is_on())) - rgi->deferred_events= new Deferred_log_events(rli); } + if ((rgi->deferred_events_collecting= rli->mi->rpl_filter->is_on()) && + !rgi->deferred_events) + rgi->deferred_events= new Deferred_log_events(rli); if (event_group_new_gtid(rgi, gtid_ev)) { free_rgi(rgi); @@ -810,11 +811,6 @@ rpl_parallel_thread::free_rgi(rpl_group_info *rgi) mysql_mutex_assert_owner(&LOCK_rpl_thread); DBUG_ASSERT(rgi->commit_orderer.waitee == NULL); rgi->free_annotate_event(); - if (rgi->deferred_events) - { - delete rgi->deferred_events; - rgi->deferred_events= NULL; - } rgi->next= rgi_free_list; rgi_free_list= rgi; }