[Commits] Rev 3973: MDEV-5754: MySQL 5.5 slaves cannot replicate from MariaDB 10.0 in http://bazaar.launchpad.net/~maria-captains/maria/10.0

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Tue Mar 4 14:10:14 EET 2014


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

------------------------------------------------------------
revno: 3973
revision-id: knielsen at knielsen-hq.org-20140304121014-jc0ipksmgzigd8ln
parent: knielsen at knielsen-hq.org-20140304074832-uak5u852hiks5zn2
committer: knielsen at knielsen-hq.org
branch nick: tmp-10.0-base
timestamp: Tue 2014-03-04 13:10:14 +0100
message:
  MDEV-5754: MySQL 5.5 slaves cannot replicate from MariaDB 10.0
  
  The problem was when a GTID event was part of a group commit, and so contained
  a commit id. The code that replaces GTID with a BEGIN event for old slaves did
  not correctly handle this case.
  
  Fix the code so that the GTID with commit id can also be properly replaced
  with a BEGIN query event. The extra two bytes are in the BEGIN event replaced
  with a dummy, empty time zone string.
=== modified file 'mysql-test/suite/rpl/r/rpl_mariadb_slave_capability.result'
--- a/mysql-test/suite/rpl/r/rpl_mariadb_slave_capability.result	2013-05-24 20:21:08 +0000
+++ b/mysql-test/suite/rpl/r/rpl_mariadb_slave_capability.result	2014-03-04 12:10:14 +0000
@@ -62,6 +62,32 @@ slave-relay-bin.000007	#	Query	#	#	# Dum
 slave-relay-bin.000007  #       Table_map       #       #       table_id: # (test.t1)
 slave-relay-bin.000007  #       Write_rows      #       #       table_id: # flags: STMT_END_F
 slave-relay-bin.000007  #       Query   #       #       COMMIT
+*** MDEV-5754: MySQL 5.5 slaves cannot replicate from MariaDB 10.0 ***
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
+SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued1 WAIT_FOR master_cont1';
+INSERT INTO t2 VALUES (1);
+SET debug_sync='now WAIT_FOR master_queued1';
+SET debug_sync='commit_after_release_LOCK_prepare_ordered SIGNAL master_queued2';
+INSERT INTO t2 VALUES (2);
+SET debug_sync='now WAIT_FOR master_queued2';
+SET debug_sync='now SIGNAL master_cont1';
+SET debug_sync='RESET';
+SET debug_sync='RESET';
+SET debug_sync='RESET';
+show binlog events in 'master-bin.000003' from <binlog_start> limit 0, 8;
+Log_name        Pos     Event_type      Server_id       End_log_pos     Info
+master-bin.000003       #       Gtid    #       #       BEGIN GTID #-#-# cid=#
+master-bin.000003       #       Table_map       #       #       table_id: # (test.t2)
+master-bin.000003       #       Write_rows      #       #       table_id: # flags: STMT_END_F
+master-bin.000003       #       Xid     #       #       COMMIT /* XID */
+master-bin.000003       #       Gtid    #       #       BEGIN GTID #-#-# cid=#
+master-bin.000003       #       Table_map       #       #       table_id: # (test.t2)
+master-bin.000003       #       Write_rows      #       #       table_id: # flags: STMT_END_F
+master-bin.000003       #       Xid     #       #       COMMIT /* XID */
+SELECT * FROM t2 ORDER BY a;
+a
+1
+2
 # Test that slave which cannot tolerate holes in binlog stream but
 # knows the event does not get dummy event
 include/stop_slave.inc
@@ -95,5 +121,5 @@ select @@global.replicate_annotate_row_e
 set @@global.debug_dbug= @old_slave_dbug;
 Clean up.
 set @@global.binlog_checksum = @old_master_binlog_checksum;
-DROP TABLE t1;
+DROP TABLE t1, t2;
 include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test'
--- a/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test	2013-05-24 20:21:08 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mariadb_slave_capability.test	2014-03-04 12:10:14 +0000
@@ -1,6 +1,8 @@
 --source include/master-slave.inc
 --source include/have_debug.inc
+--source include/have_debug_sync.inc
 --source include/have_binlog_format_row.inc
+--source include/have_innodb.inc
 
 connection master;
 
@@ -71,6 +73,52 @@ let $binlog_start= 0;
 let $binlog_limit=7,5;
 --source include/show_relaylog_events.inc
 
+
+--echo *** MDEV-5754: MySQL 5.5 slaves cannot replicate from MariaDB 10.0 ***
+
+# The problem was that for a group commit, we get commit id into the
+# GTID event, and there was a bug in the code that replaces GTID with
+# dummy that failed when commit id was present.
+#
+# So setup a group commit in InnoDB.
+
+--connection master
+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
+let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
+let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
+
+--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 t2 VALUES (1);
+
+--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 INSERT INTO t2 VALUES (2);
+
+--connection master
+SET debug_sync='now WAIT_FOR master_queued2';
+SET debug_sync='now SIGNAL master_cont1';
+
+--connection con1
+REAP;
+SET debug_sync='RESET';
+--connection con2
+REAP;
+SET debug_sync='RESET';
+--connection master
+SET debug_sync='RESET';
+let $binlog_limit= 0, 8;
+--source include/show_binlog_events.inc
+--save_master_pos
+
+--connection slave
+--sync_with_master
+SELECT * FROM t2 ORDER BY a;
+
+
 --echo # Test that slave which cannot tolerate holes in binlog stream but
 --echo # knows the event does not get dummy event
 
@@ -106,6 +154,6 @@ set @@global.debug_dbug= @old_slave_dbug
 --echo Clean up.
 connection master;
 set @@global.binlog_checksum = @old_master_binlog_checksum;
-DROP TABLE t1;
+DROP TABLE t1, t2;
 sync_slave_with_master;
 --source include/rpl_end.inc

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2014-03-03 11:13:55 +0000
+++ b/sql/log_event.cc	2014-03-04 12:10:14 +0000
@@ -3639,9 +3639,14 @@ Query_log_event::begin_event(String *pac
     DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
                 checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
 
-  /* Currently we only need to replace GTID event. */
-  DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN);
-  if (data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN)
+  /*
+    Currently we only need to replace GTID event.
+    The length of GTID differs depending on whether it contains commit id.
+  */
+  DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN ||
+              data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2);
+  if (data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN &&
+      data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2)
     return 1;
 
   flags= uint2korr(p + FLAGS_OFFSET);
@@ -3654,9 +3659,22 @@ Query_log_event::begin_event(String *pac
   int4store(q + Q_EXEC_TIME_OFFSET, 0);
   q[Q_DB_LEN_OFFSET]= 0;
   int2store(q + Q_ERR_CODE_OFFSET, 0);
-  int2store(q + Q_STATUS_VARS_LEN_OFFSET, 0);
-  q[Q_DATA_OFFSET]= 0;                    /* Zero terminator for empty db */
-  q+= Q_DATA_OFFSET + 1;
+  if (data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN)
+  {
+    int2store(q + Q_STATUS_VARS_LEN_OFFSET, 0);
+    q[Q_DATA_OFFSET]= 0;                    /* Zero terminator for empty db */
+    q+= Q_DATA_OFFSET + 1;
+  }
+  else
+  {
+    DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2);
+    /* Put in an empty time_zone_str to take up the extra 2 bytes. */
+    int2store(q + Q_STATUS_VARS_LEN_OFFSET, 2);
+    q[Q_DATA_OFFSET]= Q_TIME_ZONE_CODE;
+    q[Q_DATA_OFFSET+1]= 0;           /* Zero length for empty time_zone_str */
+    q[Q_DATA_OFFSET+2]= 0;                  /* Zero terminator for empty db */
+    q+= Q_DATA_OFFSET + 3;
+  }
   memcpy(q, "BEGIN", 5);
 
   if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2014-02-11 13:06:03 +0000
+++ b/sql/log_event.h	2014-03-04 12:10:14 +0000
@@ -3105,12 +3105,15 @@ class Binlog_checkpoint_log_event: publi
     <td>flags</td>
     <td>1 byte bitfield</td>
     <td>Bit 0 set indicates stand-alone event (no terminating COMMIT)</td>
+    <td>Bit 1 set indicates group commit, and that commit id exists</td>
   </tr>
 
   <tr>
-    <td>Reserved</td>
-    <td>6 bytes</td>
-    <td>Reserved bytes, set to 0. Maybe be used for future expansion.</td>
+    <td>Reserved (no group commit) / commit id (group commit) (see flags bit 1)</td>
+    <td>6 bytes / 8 bytes</td>
+    <td>Reserved bytes, set to 0. Maybe be used for future expansion (no
+        group commit). OR commit id, same for all GTIDs in the same group
+        commit (see flags bit 1).</td>
   </tr>
   </table>
 



More information about the commits mailing list