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;