[Commits] Rev 4072: MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts in http://bazaar.launchpad.net/~maria-captains/maria/10.0

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Thu Mar 20 16:36:45 EET 2014


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

------------------------------------------------------------
revno: 4072
revision-id: knielsen at knielsen-hq.org-20140320143645-3xdox8726y5zyv9p
parent: svoj at mariadb.org-20140320071113-ql1nx7dc9h22odx3
committer: knielsen at knielsen-hq.org
branch nick: work-10.0-mdev5914
timestamp: Thu 2014-03-20 15:36:45 +0100
message:
  MDEV-5914: Parallel replication deadlock due to InnoDB lock conflicts
  
  Preparation patch for investigating a possible solution.
  
  Add THD::rpl_group_commit_id. This will be zero except when running
  multiple transactions in parallel in parallel replication. Then it
  can be compared between two THDs to check if these are two
  transactions that were group-committed together on the master and
  thus are known not to conflict.
=== added file 'mysql-test/suite/rpl/t/rpl_mdev5914.test'
--- a/mysql-test/suite/rpl/t/rpl_mdev5914.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mdev5914.test	2014-03-20 14:36:45 +0000
@@ -0,0 +1,49 @@
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+--source include/have_debug_sync.inc
+--source include/master-slave.inc
+
+--connection slave
+--source include/stop_slave.inc
+
+--connection master
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY b_idx(b)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,NULL), (2,2), (3,NULL), (4,4), (5, NULL), (6, 6);
+
+# Create a group commit with INSERT and DELETE, in that order.
+--connect (con1,127.0.0.1,root,,test,$SERVER_MYPORT_1,)
+SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1';
+send INSERT INTO t1 VALUES (7, NULL);
+--connection master
+SET debug_sync='now WAIT_FOR master_queued1';
+
+--connect (con2,127.0.0.1,root,,test,$SERVER_MYPORT_1,)
+SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2';
+send DELETE FROM t1 WHERE b <= 3;
+
+--connection master
+SET debug_sync='now WAIT_FOR master_queued2';
+SET debug_sync='now SIGNAL master_cont1';
+
+--connection con1
+REAP;
+--connection con2
+REAP;
+SET debug_sync='RESET';
+--save_master_pos
+
+--connection slave
+SET @old_parallel= @@GLOBAL.slave_parallel_threads;
+SET GLOBAL slave_parallel_threads=16;
+--source include/start_slave.inc
+--sync_with_master
+
+SELECT * FROM t1 ORDER BY a;
+
+--source include/stop_slave.inc
+SET GLOBAL slave_parallel_threads=@old_parallel;
+--source include/start_slave.inc
+
+--connection master
+DROP TABLE t1;
+--source include/rpl_end.inc

=== modified file 'sql/rpl_parallel.cc'
--- a/sql/rpl_parallel.cc	2014-03-11 23:14:49 +0000
+++ b/sql/rpl_parallel.cc	2014-03-20 14:36:45 +0000
@@ -303,6 +303,7 @@ handle_rpl_parallel_thread(void *arg)
         bool did_enter_cond= false;
         PSI_stage_info old_stage;
         uint64 wait_count;
+        Gtid_log_event *gev= static_cast<Gtid_log_event *>(events->ev);
 
         in_event_group= true;
         /*
@@ -310,13 +311,15 @@ handle_rpl_parallel_thread(void *arg)
           single statement (possibly preceeded by some Intvar_log_event and
           similar), without any terminating COMMIT/ROLLBACK/XID.
         */
-        group_standalone=
-          (0 != (static_cast<Gtid_log_event *>(events->ev)->flags2 &
-                 Gtid_log_event::FL_STANDALONE));
+        group_standalone= (0 != (gev->flags2 & Gtid_log_event::FL_STANDALONE));
 
         /* Save this, as it gets cleared when the event group commits. */
         event_gtid_sub_id= rgi->gtid_sub_id;
 
+        if (gev->flags2 & Gtid_log_event::FL_GROUP_COMMIT_ID)
+          thd->rpl_group_commit_id= gev->commit_id;
+        else
+          thd->rpl_group_commit_id= 0;
         rgi->thd= thd;
 
         /*
@@ -482,7 +485,7 @@ handle_rpl_parallel_thread(void *arg)
       if (end_of_group)
       {
         in_event_group= false;
-        finish_event_group(thd, err, event_gtid_sub_id, entry, rgi);
+        finish_event_group(thd, (rgi->is_error?1:0), event_gtid_sub_id, entry, rgi);
         rgi->next= rgis_to_free;
         rgis_to_free= rgi;
         group_rgi= rgi= NULL;

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2014-02-26 15:38:42 +0000
+++ b/sql/sql_class.cc	2014-03-20 14:36:45 +0000
@@ -893,6 +893,7 @@ THD::THD()
 #if defined(ENABLED_DEBUG_SYNC)
    debug_sync_control(0),
 #endif /* defined(ENABLED_DEBUG_SYNC) */
+   rpl_group_commit_id(0),
    wait_for_commit_ptr(0),
     main_da(0, false, false),
    m_stmt_da(&main_da)

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2014-03-19 09:00:56 +0000
+++ b/sql/sql_class.h	2014-03-20 14:36:45 +0000
@@ -3616,6 +3616,7 @@ class THD :public Statement,
   /* Wake this thread up from wait_for_wakeup_ready(). */
   void signal_wakeup_ready();
 
+  uint64 rpl_group_commit_id;
   wait_for_commit *wait_for_commit_ptr;
   int wait_for_prior_commit()
   {



More information about the commits mailing list