[Commits] Rev 4031: MDEV-5788: Incorrect free of rgi->deferred_events in parallel replication in http://bazaar.launchpad.net/~maria-captains/maria/10.0

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Fri Mar 7 13:02:09 EET 2014


At http://bazaar.launchpad.net/~maria-captains/maria/10.0

------------------------------------------------------------
revno: 4031
revision-id: knielsen at knielsen-hq.org-20140307110209-4d9fqr28j3deiiy2
parent: sergii at pisem.net-20140305222010-umxkwveamkn2z25a
committer: knielsen at knielsen-hq.org
branch nick: tmp-10.0
timestamp: Fri 2014-03-07 12:02:09 +0100
message:
  MDEV-5788: Incorrect free of rgi->deferred_events in parallel replication
  
  When an rpl_group_info object was returned from the free list, the
  rgi->deferred_events_collecting and rgi->deferred_events was not correctly
  re-inited. Additionally, the rgi->deferred_events was incorrectly freed in
  free_rgi(), which causes unnecessary malloc/free (or crash when re-init is not
  done).
  
  Thanks to user nanyi607rao, who reported this bug on maria-developers at .
=== modified file 'mysql-test/suite/rpl/r/rpl_parallel.result'
--- a/mysql-test/suite/rpl/r/rpl_parallel.result	2014-02-26 15:38:42 +0000
+++ b/mysql-test/suite/rpl/r/rpl_parallel.result	2014-03-07 11:02:09 +0000
@@ -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

=== modified file 'mysql-test/suite/rpl/t/rpl_parallel.test'
--- a/mysql-test/suite/rpl/t/rpl_parallel.test	2014-02-26 15:38:42 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel.test	2014-03-07 11:02:09 +0000
@@ -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

=== modified file 'sql/rpl_parallel.cc'
--- a/sql/rpl_parallel.cc	2014-03-04 13:32:42 +0000
+++ b/sql/rpl_parallel.cc	2014-03-07 11:02:09 +0000
@@ -789,9 +789,10 @@ rpl_parallel_thread::get_rgi(Relay_log_i
       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_
   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;
 }



More information about the commits mailing list