From 06ffea8c5bfc351cace3997f4ea54b8dcfce2ac4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Feb 2013 21:10:40 +0100 Subject: [PATCH] MDEV-26: Global Transaction ID Fix that CHANGE MASTER ... MASTER_GTID_POS="" works to start from the very beginning of the binary log (with test case). Fix that not finding the requested GTID position in master binlog results in fatal error, not endless connect retry. --- .../suite/rpl/r/rpl_gtid_startpos.result | 40 ++++++++++++ mysql-test/suite/rpl/t/rpl_gtid_startpos.test | 63 +++++++++++++++++++ sql/log_event.cc | 4 ++ sql/sql_repl.cc | 2 +- 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/rpl/r/rpl_gtid_startpos.result create mode 100644 mysql-test/suite/rpl/t/rpl_gtid_startpos.test diff --git a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result new file mode 100644 index 00000000000..97e1e5f4dbb --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result @@ -0,0 +1,40 @@ +include/rpl_init.inc [topology=1->2] +*** Test connecting with empty GTID state to start from very beginning of binlog *** +include/stop_slave.inc +RESET MASTER; +RESET SLAVE; +RESET MASTER; +FLUSH LOGS; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, +MASTER_GTID_POS=""; +include/start_slave.inc +SELECT * FROM t1; +a +INSERT INTO t1 VALUES (1); +SELECT * FROM t1; +a +1 +include/stop_slave.inc +*** Test that master gives error when slave asks for empty gtid pos and binlog files have been purged. *** +FLUSH LOGS; +INSERT INTO t1 VALUES (2); +PURGE BINARY LOGS TO 'master-bin.000003'; +show binary logs; +Log_name File_size +master-bin.000003 # +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, +MASTER_GTID_POS=""; +START SLAVE; +include/wait_for_slave_io_error.inc [errno=1236] +include/stop_slave.inc +CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT, +MASTER_LOG_FILE="master-bin.000003", MASTER_LOG_POS=4; +include/start_slave.inc +SELECT * FROM t1 ORDER BY a; +a +1 +2 +call mtr.add_suppression('Could not find GTID state requested by slave in any binlog files'); +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test new file mode 100644 index 00000000000..2e0855afd16 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test @@ -0,0 +1,63 @@ +--source include/have_innodb.inc +--let $rpl_topology=1->2 +--source include/rpl_init.inc + +--echo *** Test connecting with empty GTID state to start from very beginning of binlog *** +--connection server_2 +--source include/stop_slave.inc +RESET MASTER; +RESET SLAVE; + +--connection server_1 +RESET MASTER; +# Create an empty binlog file, to check that empty binlog state is handled correctly. +FLUSH LOGS; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +--save_master_pos + +--connection server_2 +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_GTID_POS=""; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1; + +--connection server_1 +INSERT INTO t1 VALUES (1); +--save_master_pos + +--connection server_2 +--sync_with_master +SELECT * FROM t1; +--source include/stop_slave.inc + +--echo *** Test that master gives error when slave asks for empty gtid pos and binlog files have been purged. *** +--connection server_1 +FLUSH LOGS; +INSERT INTO t1 VALUES (2); +--save_master_pos +PURGE BINARY LOGS TO 'master-bin.000003'; +--source include/show_binary_logs.inc + +--connection server_2 +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_GTID_POS=""; +START SLAVE; +--let $slave_io_errno= 1236 +--source include/wait_for_slave_io_error.inc +--source include/stop_slave.inc + +--replace_result $MASTER_MYPORT MASTER_PORT +eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT, + MASTER_LOG_FILE="master-bin.000003", MASTER_LOG_POS=4; +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; +call mtr.add_suppression('Could not find GTID state requested by slave in any binlog files'); + +--connection server_1 +DROP TABLE t1; + +--source include/rpl_end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index 270454f0051..33f3fb2c368 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6579,6 +6579,8 @@ rpl_slave_state::load(THD *thd, char *state_from_master, size_t len, return 1; truncate_hash(); } + if (state_from_master == end) + return 0; for (;;) { rpl_gtid gtid; @@ -6856,6 +6858,8 @@ slave_connection_state::load(char *slave_request, size_t len) my_hash_reset(&hash); p= slave_request; end= slave_request + len; + if (p == end) + return 0; for (;;) { if (!(rec= (uchar *)my_malloc(sizeof(*gtid), MYF(MY_WME)))) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index d9f4c1f0b0e..db4153becdf 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1292,7 +1292,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, } if ((errmsg= gtid_find_binlog_file(>id_state, search_file_name))) { - my_errno= ER_UNKNOWN_ERROR; + my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; goto err; } pos= 4;