List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:October 23 2007 8:10pm
Subject:bk commit into 5.0 tree (mats:1.2544) BUG#12691
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of mats. When mats does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-10-23 22:10:23+02:00, mats@stripped +1 -0
  BUG#12691 (Exec_master_log_pos corrupted with SQL_SLAVE_SKIP_COUNTER):
  
  Adding code to keep skipping events while inside a transaction. Execution
  will start just after the transaction has been skipped.

  sql/slave.cc@stripped, 2007-10-23 22:10:17+02:00, mats@stripped +53 -3
    Adding code to set the thd->options flag for the slave SQL thread
    even when BEGIN, ROLLBACK, COMMIT, and XID events are being skipped.
    
    Adding code to not decrease the slave skip counter from 1 to 0 if we
    are inside a transaction. This will keep the counter at 1, and keep
    skipping events, until a transaction terminator is read. At that point,
    the slave skip counter will be decreased to 0, and events will be read
    and executed instead of read and skipped.

diff -Nrup a/sql/slave.cc b/sql/slave.cc
--- a/sql/slave.cc	2007-10-04 17:46:29 +02:00
+++ b/sql/slave.cc	2007-10-23 22:10:17 +02:00
@@ -3279,7 +3279,43 @@ static int exec_relay_log_event(THD* thd
       now the relay log starts with its Format_desc, has a Rotate etc).
     */
 
-    DBUG_PRINT("info",("type_code=%d, server_id=%d",type_code,ev->server_id));
+    DBUG_PRINT("info",("type_code: %d; server_id: %d; slave_skip_counter: %d",
+                       type_code, ev->server_id, rli->slave_skip_counter));
+
+    /*
+      If the slave skip counter is positive, we still need to set the
+      OPTION_BEGIN flag correctly and not skip the log events that
+      start or end a transaction. If we do this, the slave will not
+      notice that it is inside a transaction, and happily start
+      executing from inside the transaction.
+
+      Note that the code block below is strictly 5.0.
+     */
+#if MYSQL_VERSION_ID < 50100
+    if (unlikely(rli->slave_skip_counter > 0))
+    {
+      switch (type_code)
+      {
+      case QUERY_EVENT:
+      {
+        Query_log_event* const qev= (Query_log_event*) ev;
+        DBUG_PRINT("info", ("QUERY_EVENT { query: '%s', q_len: %u }",
+                            qev->query, qev->q_len));
+        if (memcmp("BEGIN", qev->query, qev->q_len) == 0)
+          thd->options|= OPTION_BEGIN;
+        else if (memcmp("COMMIT", qev->query, qev->q_len) == 0 ||
+                 memcmp("ROLLBACK", qev->query, qev->q_len) == 0)
+          thd->options&= ~OPTION_BEGIN;
+      }
+      break;
+
+      case XID_EVENT:
+        DBUG_PRINT("info", ("XID_EVENT"));
+        thd->options&= ~OPTION_BEGIN;
+        break;
+      }
+    }
+#endif
 
     if ((ev->server_id == (uint32) ::server_id &&
          !replicate_same_server_id &&
@@ -3301,6 +3337,9 @@ static int exec_relay_log_event(THD* thd
         flush_relay_log_info(rli);
       }
 
+      DBUG_PRINT("info", ("thd->options: %s",
+                          (thd->options & OPTION_BEGIN) ? "OPTION_BEGIN" : ""))
+
       /*
         Protect against common user error of setting the counter to 1
         instead of 2 while recovering from an insert which used auto_increment,
@@ -3321,8 +3360,19 @@ static int exec_relay_log_event(THD* thd
             would not be skipped.
           */
           !(ev->server_id == (uint32) ::server_id &&
-            (type_code == ROTATE_EVENT || type_code == STOP_EVENT ||
-             type_code == START_EVENT_V3 || type_code == FORMAT_DESCRIPTION_EVENT)))
+            (type_code == ROTATE_EVENT ||
+             type_code == STOP_EVENT ||
+             type_code == START_EVENT_V3 ||
+             type_code == FORMAT_DESCRIPTION_EVENT)) &&
+#if MYSQL_VERSION_ID < 50100
+          /*
+            Decrease the slave skip counter only if we are not inside
+            a transaction or the slave skip counter is more than
+            1. The slave skip counter will be decreased from 1 to 0
+            when reaching the final ROLLBACK, COMMIT, or XID_EVENT.
+           */
+          (!(thd->options & OPTION_BEGIN)) || rli->slave_skip_counter > 1)
+#endif
         --rli->slave_skip_counter;
       pthread_mutex_unlock(&rli->data_lock);
       delete ev;
Thread
bk commit into 5.0 tree (mats:1.2544) BUG#12691Mats Kindahl23 Oct