From 20e021115fac345c8c6a9b6c4d6512e0f93f816a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Mar 2013 09:37:54 +0100 Subject: [PATCH] MDEV-26: Global transaction ID. Fix MDEV-4329. When user does CHANGE MASTER TO MASTER_GTID_POS='', we check that this state does not conflict with the binlog. But the code forgot to give an error in the case where a domain was completely missing from the requested position (eg. MASTER_GTID_POS=''). --- .../suite/rpl/r/rpl_gtid_errorhandling.result | 2 + .../suite/rpl/r/rpl_gtid_startpos.result | 24 ++++++++++++ .../suite/rpl/t/rpl_gtid_errorhandling.test | 2 + mysql-test/suite/rpl/t/rpl_gtid_startpos.test | 39 +++++++++++++++++++ sql/share/errmsg-utf8.txt | 2 + sql/sql_repl.cc | 7 +++- 6 files changed, 75 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result b/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result index 3ff6fe10e4a..7924ae6bec1 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result @@ -40,6 +40,8 @@ SET sql_log_bin = 1; INSERT INTO t1 VALUES (3); CHANGE MASTER TO master_gtid_pos = "0-1-1"; ERROR HY000: Requested MASTER_GTID_POS 0-1-1 conflicts with the binary log which contains a more recent GTID 0-2-11. To use the requested MASTER_GTID_POS, the old binlog must be removed with RESET MASTER to avoid out-of-order binlog +CHANGE MASTER TO master_gtid_pos = ""; +ERROR HY000: Requested MASTER_GTID_POS contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-11. To use the requested MASTER_GTID_POS, the old binlog must be removed with RESET MASTER to avoid out-of-order binlog RESET MASTER; CHANGE MASTER TO master_gtid_pos = "0-1-1"; START SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result index 13712c910f7..70af8eae6ef 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_startpos.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_startpos.result @@ -87,5 +87,29 @@ SELECT * FROM t1 ORDER BY a; a 1 2 +*** MDEV-4329: MASTER_GTID_POS='' is not checked for conflicts with binlog *** +include/stop_slave.inc +DROP TABLE t1; +RESET SLAVE; +CHANGE MASTER TO master_gtid_pos=''; +ERROR HY000: Requested MASTER_GTID_POS contains no value for replication domain 0. This conflicts with the binary log which contains GTID 0-2-4. To use the requested MASTER_GTID_POS, the old binlog must be removed with RESET MASTER to avoid out-of-order binlog +RESET MASTER; +CHANGE MASTER TO master_gtid_pos=''; +include/start_slave.inc +SELECT * FROM t1 ORDER BY a; +a +1 +2 +include/stop_slave.inc +SET SQL_LOG_BIN=0; +DROP TABLE t1; +SET SQL_LOG_BIN=1; +RESET SLAVE; +CHANGE MASTER TO master_gtid_pos=''; +include/start_slave.inc +SELECT * FROM t1 ORDER BY a; +a +1 +2 DROP TABLE t1; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test index 7f4e220c86b..2720d8c5028 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test @@ -71,6 +71,8 @@ INSERT INTO t1 VALUES (3); --error ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG CHANGE MASTER TO master_gtid_pos = "0-1-1"; +--error ER_MASTER_GTID_POS_MISSING_DOMAIN +CHANGE MASTER TO master_gtid_pos = ""; RESET MASTER; CHANGE MASTER TO master_gtid_pos = "0-1-1"; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test index 32fb608080c..d2e2303a588 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_startpos.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_startpos.test @@ -143,6 +143,45 @@ INSERT INTO t1 VALUES (2); SELECT * FROM t1 ORDER BY a; + +--echo *** MDEV-4329: MASTER_GTID_POS='' is not checked for conflicts with binlog *** + +# Test starting the slave completely from scratch, deleting all tables and +# replicating from the start of the master's binlog. This requires RESET +# MASTER is run on the slave to avoid old junk in the binlog. The bug was +# that the code did not catch the error of missing RESET MASTER when an +# empty MASTER_GTID_POS='' was specified. + +--connection server_2 +--source include/stop_slave.inc +DROP TABLE t1; +RESET SLAVE; +--error ER_MASTER_GTID_POS_MISSING_DOMAIN +eval CHANGE MASTER TO master_gtid_pos=''; +RESET MASTER; +eval CHANGE MASTER TO master_gtid_pos=''; + +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + +# Same thing, but this time using SQL_LOG_BIN=0 to avoid polliting the +# slave binlog. + +--connection server_2 +--source include/stop_slave.inc +SET SQL_LOG_BIN=0; +DROP TABLE t1; +SET SQL_LOG_BIN=1; +RESET SLAVE; +eval CHANGE MASTER TO master_gtid_pos=''; + +--source include/start_slave.inc +--sync_with_master +SELECT * FROM t1 ORDER BY a; + + # Clean up. --connection server_1 DROP TABLE t1; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index aa19d2c9c05..3ee66ae2a7a 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6617,3 +6617,5 @@ ER_CANNOT_LOAD_SLAVE_GTID_STATE eng "Failed to load replication slave GTID state from table %s.%s" ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG eng "Requested MASTER_GTID_POS %u-%u-%llu conflicts with the binary log which contains a more recent GTID %u-%u-%llu. To use the requested MASTER_GTID_POS, the old binlog must be removed with RESET MASTER to avoid out-of-order binlog" +ER_MASTER_GTID_POS_MISSING_DOMAIN + eng "Requested MASTER_GTID_POS contains no value for replication domain %u. This conflicts with the binary log which contains GTID %u-%u-%llu. To use the requested MASTER_GTID_POS, the old binlog must be removed with RESET MASTER to avoid out-of-order binlog" diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 3c6a4588c36..57e85810808 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2533,7 +2533,12 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added) if (binlog_gtid->server_id != global_system_variables.server_id) continue; if (!(slave_gtid= tmp_slave_state.find(binlog_gtid->domain_id))) - continue; + { + my_error(ER_MASTER_GTID_POS_MISSING_DOMAIN, MYF(0), + binlog_gtid->domain_id, binlog_gtid->domain_id, + binlog_gtid->server_id, binlog_gtid->seq_no); + break; + } if (slave_gtid->seq_no < binlog_gtid->seq_no) { my_error(ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG, MYF(0),