[Commits] Rev 3457: MDEV-26: Global transaction ID in http://bazaar.launchpad.net/~maria-captains/maria/10.0

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Thu Feb 21 09:10:56 EET 2013


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

------------------------------------------------------------
revno: 3457
revision-id: knielsen at knielsen-hq.org-20130221071055-4bv9kkwa5y19dg8e
parent: knielsen at knielsen-hq.org-20130219132229-oy70ythytiqqcsnm
committer: knielsen at knielsen-hq.org
branch nick: work-10.0-mdev26
timestamp: Thu 2013-02-21 08:10:55 +0100
message:
  MDEV-26: Global transaction ID
  
   - Add first basic mysql-test-run test case which tests switch to new master
     using MASTER_GTID_POS=AUTO.
  
   - When we connect with GTID, do not use any old relay logs, as they may
     contain the wrong events or be corrupt after crash.
  
   - Fix old bug that fails replication if we receive a heartbeat event
     immediately after an event was omitted in the stream from the master.
  
   - Fix rpl_end to clear Gtid_Pos_Auto, to keep check_testcase happy.
=== modified file 'mysql-test/include/rpl_end.inc'
--- a/mysql-test/include/rpl_end.inc	2010-12-20 14:15:01 +0000
+++ b/mysql-test/include/rpl_end.inc	2013-02-21 07:10:55 +0000
@@ -79,6 +79,22 @@ while ($_rpl_server)
 --source include/rpl_sync.inc
 --source include/rpl_stop_slaves.inc
 
+if (!$rpl_debug)
+{
+  --disable_query_log
+}
+--let $_rpl_server= $rpl_server_count
+while ($_rpl_server)
+{
+  --let $rpl_connection_name= server_$_rpl_server
+  --source include/rpl_connection.inc
+
+  # Clear Gtid_Pos_Auto in SHOW SLAVE STATUS to keep check_testcase happy.
+  CHANGE MASTER TO master_log_file='';
+
+  --dec $_rpl_server
+}
+
 # mtr configures server 2 to be a slave before it runs the test. We
 # have to restore that state now, so we change topology to 1->2.
 --let $rpl_topology= none

=== modified file 'mysql-test/suite/rpl/r/rpl_gtid_basic.result'
--- a/mysql-test/suite/rpl/r/rpl_gtid_basic.result	2013-02-18 14:41:17 +0000
+++ b/mysql-test/suite/rpl/r/rpl_gtid_basic.result	2013-02-21 07:10:55 +0000
@@ -44,5 +44,74 @@ a	b
 2       i2
 3       i3
 4       i4
+*** Now take out D, let it fall behind a bit, and then test re-attaching it to A ***
+include/stop_slave.inc
+INSERT INTO t1 VALUES (5, "m1a");
+INSERT INTO t2 VALUES (5, "i1a");
+CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT,
+MASTER_GTID_POS=AUTO;
+include/start_slave.inc
+SELECT * FROM t1 ORDER BY a;
+a       b
+1       m1
+2       m2
+3       m3
+4       m4
+5       m1a
+SELECT * FROM t2 ORDER BY a;
+a       b
+1       i1
+2       i2
+3       i3
+4       i4
+5       i1a
+*** Now move B to D (C is still replicating from B) ***
+include/stop_slave.inc
+CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4,
+MASTER_GTID_POS=AUTO;
+include/start_slave.inc
+UPDATE t2 SET b="j1a" WHERE a=5;
+SELECT * FROM t1 ORDER BY a;
+a       b
+1       m1
+2       m2
+3       m3
+4       m4
+5       m1a
+SELECT * FROM t2 ORDER BY a;
+a       b
+1       i1
+2       i2
+3       i3
+4       i4
+5       j1a
+*** Now move C to D, after letting it fall a little behind ***
+include/stop_slave.inc
+BEGIN;
+INSERT INTO t2 VALUES (6, "i6b");
+INSERT INTO t2 VALUES (7, "i7b");
+COMMIT;
+CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_4,
+MASTER_GTID_POS=AUTO;
+include/start_slave.inc
+SELECT * FROM t2 ORDER BY a;
+a       b
+1       i1
+2       i2
+3       i3
+4       i4
+5       j1a
+6       i6b
+7       i7b
+*** Now change everything back to what it was, to make rpl_end.inc happy
+include/stop_slave.inc
+CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_MYPORT;
+include/start_slave.inc
+include/stop_slave.inc
+CHANGE MASTER TO master_host = '127.0.0.1', master_port = SLAVE_MYPORT;
+include/start_slave.inc
+include/stop_slave.inc
+CHANGE MASTER TO master_host = '127.0.0.1', master_port = SERVER_MYPORT_3;
+include/start_slave.inc
 DROP TABLE t1,t2;
 include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/t/rpl_gtid_basic.test'
--- a/mysql-test/suite/rpl/t/rpl_gtid_basic.test	2013-02-18 14:41:17 +0000
+++ b/mysql-test/suite/rpl/t/rpl_gtid_basic.test	2013-02-21 07:10:55 +0000
@@ -2,6 +2,11 @@
 --let $rpl_topology=1->2->3->4
 --source include/rpl_init.inc
 
+# Set up a 4-deep replication topology, then test various fail-overs
+# using GTID.
+#
+#  A -> B -> C -> D
+
 connection server_1;
 CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=MyISAM;
 CREATE TABLE t2 (a INT PRIMARY KEY, b VARCHAR(10)) ENGINE=InnoDB;
@@ -31,6 +36,82 @@ sync_with_master;
 SELECT * FROM t1 ORDER BY a;
 SELECT * FROM t2 ORDER BY a;
 
+
+--echo *** Now take out D, let it fall behind a bit, and then test re-attaching it to A ***
+connection server_4;
+--source include/stop_slave.inc
+
+connection server_1;
+INSERT INTO t1 VALUES (5, "m1a");
+INSERT INTO t2 VALUES (5, "i1a");
+save_master_pos;
+
+connection server_4;
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT,
+     MASTER_GTID_POS=AUTO;
+--source include/start_slave.inc
+sync_with_master;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+--echo *** Now move B to D (C is still replicating from B) ***
+connection server_2;
+--source include/stop_slave.inc
+--replace_result $SERVER_MYPORT_4 SERVER_MYPORT_4
+eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_4,
+     MASTER_GTID_POS=AUTO;
+--source include/start_slave.inc
+
+connection server_4;
+UPDATE t2 SET b="j1a" WHERE a=5;
+save_master_pos;
+
+connection server_2;
+sync_with_master;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+--echo *** Now move C to D, after letting it fall a little behind ***
+connection server_3;
+--source include/stop_slave.inc
+
+connection server_1;
+BEGIN;
+INSERT INTO t2 VALUES (6, "i6b");
+INSERT INTO t2 VALUES (7, "i7b");
+COMMIT;
+
+connection server_3;
+--replace_result $SERVER_MYPORT_4 SERVER_MYPORT_4
+eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_4,
+     MASTER_GTID_POS=AUTO;
+--source include/start_slave.inc
+# This time, let's sync up without reference to binlog on D.
+--let $wait_condition= SELECT COUNT(*) = 7 FROM t2
+--source include/wait_condition.inc
+SELECT * FROM t2 ORDER BY a;
+
+--echo *** Now change everything back to what it was, to make rpl_end.inc happy
+# Also check that MASTER_GTID_POS=AUTO is still enabled.
+connection server_2;
+--source include/stop_slave.inc
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT;
+--source include/start_slave.inc
+
+connection server_3;
+--source include/stop_slave.inc
+--replace_result $SLAVE_MYPORT SLAVE_MYPORT
+eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SLAVE_MYPORT;
+--source include/start_slave.inc
+
+connection server_4;
+--source include/stop_slave.inc
+--replace_result $SERVER_MYPORT_3 SERVER_MYPORT_3
+eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $SERVER_MYPORT_3;
+--source include/start_slave.inc
+
 connection server_1;
 DROP TABLE t1,t2;
 

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2013-02-19 10:45:29 +0000
+++ b/sql/slave.cc	2013-02-21 07:10:55 +0000
@@ -397,6 +397,33 @@ int init_recovery(Master_info* mi, const
 
   DBUG_RETURN(0);
 }
+
+
+/*
+  When connecting a slave to a master with GTID, we reset the relay log
+  coordinates of the SQL thread and clear the master coordinates of SQL and IO
+  threads.
+
+  This way we ensure that we start from the correct place even after a change
+  to new master or a crash where relay log coordinates may be wrong (GTID
+  state is crash safe but master.info is not). And we get the correct master
+  coordinates set upon reading the initial fake rotate event sent from master.
+*/
+static void
+reset_coordinates_for_gtid(Master_info *mi, Relay_log_info *rli)
+{
+  mi->master_log_pos= 0;
+  mi->master_log_name[0]= 0;
+  rli->group_master_log_pos= 0;
+  rli->group_master_log_name[0]= 0;
+  rli->group_relay_log_pos= BIN_LOG_HEADER_SIZE;
+  strmake(rli->group_relay_log_name, rli->relay_log.get_log_fname(),
+          sizeof(rli->group_relay_log_name)-1);
+  rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
+  strmake(rli->event_relay_log_name, rli->relay_log.get_log_fname(),
+          sizeof(mi->rli.event_relay_log_name)-1);
+}
+
  
 /**
   Convert slave skip errors bitmap into a printable string.
@@ -3384,6 +3411,8 @@ pthread_handler_t handle_slave_io(void *
   if (ret == 1)
     /* Fatal error */
     goto err;
+  if (mi->gtid_pos_auto)
+    reset_coordinates_for_gtid(mi, rli);
 
   if (ret == 2) 
   { 
@@ -4697,16 +4726,18 @@ static int queue_event(Master_info* mi,c
        
        Heartbeat is sent only after an event corresponding to the corrdinates
        the heartbeat carries.
-       Slave can not have a difference in coordinates except in the only
+       Slave can not have a higher coordinate except in the only
        special case when mi->master_log_name, master_log_pos have never
        been updated by Rotate event i.e when slave does not have any history
        with the master (and thereafter mi->master_log_pos is NULL).
 
+       Slave can have lower coordinates, if some event from master was omitted.
+
        TODO: handling `when' for SHOW SLAVE STATUS' snds behind
     */
     if ((memcmp(mi->master_log_name, hb.get_log_ident(), hb.get_ident_len())
          && mi->master_log_name != NULL)
-        || mi->master_log_pos != hb.log_pos)
+        || mi->master_log_pos > hb.log_pos)
     {
       /* missed events of heartbeat from the past */
       error= ER_SLAVE_HEARTBEAT_FAILURE;



More information about the commits mailing list