[Commits] bd2ae78: MDEV-7825: Parallel replication race condition on gco->flags, possibly resulting in slave hang

Kristian Nielsen knielsen at knielsen-hq.org
Tue Mar 24 17:35:50 EET 2015


revision-id: bd2ae787ea273169dc88db62bc1e66d56cbe9a4c
parent(s): ec68494beb151bc01ff6885476d2d4aeab3fe345
committer: Kristian Nielsen
branch nick: mariadb
timestamp: 2015-03-24 16:33:51 +0100
message:

MDEV-7825: Parallel replication race condition on gco->flags, possibly resulting in slave hang

The patch for optimistic parallel replication as a memory optimisation moved
the gco->installed field into a bit in gco->flags. However, that is just plain
wrong. The gco->flags field is owned by the SQL driver thread, but
gco->installed is used by the worker threads, so this will cause a race
condition.

The user-visible problem might be conflicts between transactions and/or slave
threads hanging.

So revert this part of the optimistic parallel replication patch, going back
to using a separate field gco->installed like in 10.0.

---
 sql/rpl_parallel.cc | 5 +++--
 sql/rpl_parallel.h  | 7 ++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 5a81db4..1e24db2 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -744,7 +744,7 @@ handle_rpl_parallel_thread(void *arg)
           in parallel with.
         */
         mysql_mutex_lock(&entry->LOCK_parallel_entry);
-        if (!(gco->flags & group_commit_orderer::INSTALLED))
+        if (!gco->installed)
         {
           group_commit_orderer *prev_gco= gco->prev_gco;
           if (prev_gco)
@@ -752,7 +752,7 @@ handle_rpl_parallel_thread(void *arg)
             prev_gco->last_sub_id= gco->prior_sub_id;
             prev_gco->next_gco= gco;
           }
-          gco->flags|= group_commit_orderer::INSTALLED;
+          gco->installed= true;
         }
         wait_count= gco->wait_count;
         if (wait_count > entry->count_committing_event_groups)
@@ -1401,6 +1401,7 @@ rpl_parallel_thread::get_gco(uint64 wait_count, group_commit_orderer *prev,
   gco->prev_gco= prev;
   gco->next_gco= NULL;
   gco->prior_sub_id= prior_sub_id;
+  gco->installed= false;
   gco->flags= 0;
   return gco;
 }
diff --git a/sql/rpl_parallel.h b/sql/rpl_parallel.h
index eebb8d1..9313997 100644
--- a/sql/rpl_parallel.h
+++ b/sql/rpl_parallel.h
@@ -66,7 +66,8 @@ struct group_commit_orderer {
     This flag is set when this GCO has been installed into the next_gco pointer
     of the previous GCO.
   */
-  static const uint8 INSTALLED = 0x01;
+  bool installed;
+
   /*
     This flag is set for a GCO in which we have event groups with multiple
     different commit_id values from the master. This happens when we
@@ -77,13 +78,13 @@ struct group_commit_orderer {
     of current commit_id, as DDL is not safe to speculatively apply in parallel
     with prior event groups.
   */
-  static const uint8 MULTI_BATCH = 0x02;
+  static const uint8 MULTI_BATCH = 0x01;
   /*
     This flag is set for a GCO that contains DDL. If set, it forces a switch to
     a new GCO upon seeing a new commit_id, as DDL is not safe to speculatively
     replicate in parallel with subsequent transactions.
   */
-  static const uint8 FORCE_SWITCH = 0x04;
+  static const uint8 FORCE_SWITCH = 0x02;
   uint8 flags;
 };
 


More information about the commits mailing list