diff options
author | Kristian Nielsen <knielsen@knielsen-hq.org> | 2014-06-24 14:43:08 +0200 |
---|---|---|
committer | Kristian Nielsen <knielsen@knielsen-hq.org> | 2014-06-24 14:43:08 +0200 |
commit | 312219cc63fd49734b3369cc41cdc0f5cf2aaa7f (patch) | |
tree | 907dfdf08ea24e93abb755227638a18aa428baab | |
parent | e0c8d729a27ae3a8a1a6c5e6e64f0380381f53d5 (diff) | |
download | mariadb-git-312219cc63fd49734b3369cc41cdc0f5cf2aaa7f.tar.gz |
MDEV-6364: Migrate a slave from MySQL 5.6 to MariaDB 10 break replication
MySQL 5.6 implemented WL#344, which is about a MASTER_DELAY option to CHANGE
MASTER. But as part of this worklog, the format of the realy-log.info file was
changed. The new format is not understood by earlier versions, and nor by
MariaDB 10.0, so changing server to those versions would cause the slave to
abort with an error due to reading incorrect data out of relay-log.info.
Fix this by backporting from the WL#344 patch just the code that understands
the new relay-log.info format. We still write out the old format, and none of
the MASTER_DELAY feature is backported with this commit.
-rw-r--r-- | client/mysqltest.cc | 4 | ||||
-rw-r--r-- | mysql-test/std_data/new-format-relay-log-win.info | 6 | ||||
-rw-r--r-- | mysql-test/std_data/new-format-relay-log.info | 6 | ||||
-rw-r--r-- | mysql-test/std_data/old-format-relay-log-win.info | 4 | ||||
-rw-r--r-- | mysql-test/std_data/old-format-relay-log.info | 4 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_read_old_relay_log_info.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test | 43 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test | 44 | ||||
-rw-r--r-- | sql/rpl_rli.cc | 74 | ||||
-rw-r--r-- | sql/rpl_rli.h | 6 |
11 files changed, 212 insertions, 7 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index ef339d17a42..464ec0f0199 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -8990,6 +8990,10 @@ int main(int argc, char **argv) 128, 0, 0, get_var_key, 0, var_free, MYF(0))) die("Variable hash initialization failed"); + { + char path_separator[]= { FN_LIBCHAR, 0 }; + var_set_string("SYSTEM_PATH_SEPARATOR", path_separator); + } var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); var_set_string("MYSQL_SYSTEM_TYPE", SYSTEM_TYPE); var_set_string("MYSQL_MACHINE_TYPE", MACHINE_TYPE); diff --git a/mysql-test/std_data/new-format-relay-log-win.info b/mysql-test/std_data/new-format-relay-log-win.info new file mode 100644 index 00000000000..e00383b5565 --- /dev/null +++ b/mysql-test/std_data/new-format-relay-log-win.info @@ -0,0 +1,6 @@ +5 +.\slave-relay-bin.000001 +4 + +0 +0 diff --git a/mysql-test/std_data/new-format-relay-log.info b/mysql-test/std_data/new-format-relay-log.info new file mode 100644 index 00000000000..883dec1f66b --- /dev/null +++ b/mysql-test/std_data/new-format-relay-log.info @@ -0,0 +1,6 @@ +5 +./slave-relay-bin.000001 +4 + +0 +0 diff --git a/mysql-test/std_data/old-format-relay-log-win.info b/mysql-test/std_data/old-format-relay-log-win.info new file mode 100644 index 00000000000..7673de6b956 --- /dev/null +++ b/mysql-test/std_data/old-format-relay-log-win.info @@ -0,0 +1,4 @@ +.\slave-relay-bin.000001 +4 + +0 diff --git a/mysql-test/std_data/old-format-relay-log.info b/mysql-test/std_data/old-format-relay-log.info new file mode 100644 index 00000000000..6043b4058f6 --- /dev/null +++ b/mysql-test/std_data/old-format-relay-log.info @@ -0,0 +1,4 @@ +./slave-relay-bin.000001 +4 + +0 diff --git a/mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result b/mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result new file mode 100644 index 00000000000..e659c3ee283 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result @@ -0,0 +1,14 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +==== Check that we can understand the new format of relay-log.info ==== +include/stop_slave.inc +RESET SLAVE; +# Read relay-log.info +START SLAVE IO_THREAD; +include/wait_for_slave_io_to_start.inc +# Check that relay log coordinates are equal to those saved in new-format_relay-log.info += , 0, slave-relay-bin.000001, 4 +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_read_old_relay_log_info.result b/mysql-test/suite/rpl/r/rpl_read_old_relay_log_info.result new file mode 100644 index 00000000000..7a9d3b795d8 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_read_old_relay_log_info.result @@ -0,0 +1,14 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +==== Check that we still understand the old format of relay-log.info ==== +include/stop_slave.inc +RESET SLAVE; +# Read relay-log.info +START SLAVE IO_THREAD; +include/wait_for_slave_io_to_start.inc +# Check that relay log coordinates are equal to those we saved in old-format_relay-log.info += , 0, slave-relay-bin.000001, 4 +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test b/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test new file mode 100644 index 00000000000..1e2c8ce2d9f --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test @@ -0,0 +1,43 @@ +# ==== Purpose ==== +# +# - Verify that the post-WL#344 format of relay_log.info can be parsed. + +--source include/master-slave.inc + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +--sync_slave_with_master + +--echo ==== Check that we can understand the new format of relay-log.info ==== +--source include/stop_slave.inc + +RESET SLAVE; +--let $MYSQLD_DATADIR= `select @@datadir` + +# the new version of relay_log.info comes in two versions: with path +# separator '/' (most systems) and with path separator '\' (windows) +if ($SYSTEM_PATH_SEPARATOR != /) { + --let $file_suffix= -win +} +--copy_file $MYSQL_TEST_DIR/std_data/new-format-relay-log$file_suffix.info $MYSQLD_DATADIR/relay-log.info + +--echo # Read relay-log.info +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc +--echo # Check that relay log coordinates are equal to those saved in new-format_relay-log.info +--let $master_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $master_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +--let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--let $relay_log_pos= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +--echo $master_file= $master_file, $master_pos, $relay_log_file, $relay_log_pos +if (`SELECT "$master_file" != "" OR + "$master_pos" != "0" OR + "$relay_log_file" != "slave-relay-bin.000001" OR + "$relay_log_pos" != "4"`) { + --echo ERROR: log coordinates changed + --die log coordinates changed +} + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test b/mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test new file mode 100644 index 00000000000..ce345445c08 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test @@ -0,0 +1,44 @@ +# ==== Purpose ==== +# +# - Verify that the pre-WL#344 format of relay_log.info can still be +# parsed. + +--source include/master-slave.inc + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +DROP TABLE t1; +--sync_slave_with_master + +--echo ==== Check that we still understand the old format of relay-log.info ==== +--source include/stop_slave.inc + +RESET SLAVE; +--let $MYSQLD_DATADIR= `select @@datadir` + +# the old version of relay_log.info comes in two versions: with path +# separator '/' (most systems) and with path separator '\' (windows) +if ($SYSTEM_PATH_SEPARATOR != /) { + --let $file_suffix= -win +} +--copy_file $MYSQL_TEST_DIR/std_data/old-format-relay-log$file_suffix.info $MYSQLD_DATADIR/relay-log.info + +--echo # Read relay-log.info +START SLAVE IO_THREAD; +--source include/wait_for_slave_io_to_start.inc +--echo # Check that relay log coordinates are equal to those we saved in old-format_relay-log.info +--let $master_file= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1) +--let $master_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) +--let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--let $relay_log_pos= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1) +--echo $master_file= $master_file, $master_pos, $relay_log_file, $relay_log_pos +if (`SELECT "$master_file" != "" OR + "$master_pos" != "0" OR + "$relay_log_file" != "slave-relay-bin.000001" OR + "$relay_log_pos" != "4"`) { + --echo ERROR: log coordinates changed + --die log coordinates changed +} + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index a162d1d79f8..9de23e3cca6 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -305,20 +305,80 @@ Failed to open the existing relay log info file '%s' (errno %d)", } rli->info_fd = info_fd; - int relay_log_pos, master_log_pos; + int relay_log_pos, master_log_pos, lines; + char *first_non_digit; + /* + In MySQL 5.6, there is a MASTER_DELAY option to CHANGE MASTER. This is + not yet merged into MariaDB (as of 10.0.13). However, we detect the + presense of the new option in relay-log.info, as a placeholder for + possible later merge of the feature, and to maintain file format + compatibility with MySQL 5.6+. + */ + int dummy_sql_delay; + + /* + Starting from MySQL 5.6.x, relay-log.info has a new format. + Now, its first line contains the number of lines in the file. + By reading this number we can determine which version our master.info + comes from. We can't simply count the lines in the file, since + versions before 5.6.x could generate files with more lines than + needed. If first line doesn't contain a number, or if it + contains a number less than LINES_IN_RELAY_LOG_INFO_WITH_DELAY, + then the file is treated like a file from pre-5.6.x version. + There is no ambiguity when reading an old master.info: before + 5.6.x, the first line contained the binlog's name, which is + either empty or has an extension (contains a '.'), so can't be + confused with an integer. + + So we're just reading first line and trying to figure which + version is this. + */ + + /* + The first row is temporarily stored in mi->master_log_name, if + it is line count and not binlog name (new format) it will be + overwritten by the second row later. + */ if (init_strvar_from_file(rli->group_relay_log_name, sizeof(rli->group_relay_log_name), + &rli->info_file, "")) + { + msg="Error reading slave log configuration"; + goto err; + } + + lines= strtoul(rli->group_relay_log_name, &first_non_digit, 10); + + if (rli->group_relay_log_name[0] != '\0' && + *first_non_digit == '\0' && + lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY) + { + DBUG_PRINT("info", ("relay_log_info file is in new format.")); + /* Seems to be new format => read relay log name from next line */ + if (init_strvar_from_file(rli->group_relay_log_name, + sizeof(rli->group_relay_log_name), + &rli->info_file, "")) + { + msg="Error reading slave log configuration"; + goto err; + } + } + else + DBUG_PRINT("info", ("relay_log_info file is in old format.")); + + if (init_intvar_from_file(&relay_log_pos, + &rli->info_file, BIN_LOG_HEADER_SIZE) || + init_strvar_from_file(rli->group_master_log_name, + sizeof(rli->group_master_log_name), &rli->info_file, "") || - init_intvar_from_file(&relay_log_pos, - &rli->info_file, BIN_LOG_HEADER_SIZE) || - init_strvar_from_file(rli->group_master_log_name, - sizeof(rli->group_master_log_name), - &rli->info_file, "") || - init_intvar_from_file(&master_log_pos, &rli->info_file, 0)) + init_intvar_from_file(&master_log_pos, &rli->info_file, 0) || + (lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY && + init_intvar_from_file(&dummy_sql_delay, &rli->info_file, 0))) { msg="Error reading slave log configuration"; goto err; } + strmake_buf(rli->event_relay_log_name,rli->group_relay_log_name); rli->group_relay_log_pos= rli->event_relay_log_pos= relay_log_pos; rli->group_master_log_pos= master_log_pos; diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index 137571ab820..63791a6389c 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -28,6 +28,12 @@ struct RPL_TABLE_LIST; class Master_info; class Rpl_filter; + +enum { + LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 5 +}; + + /**************************************************************************** Replication SQL Thread |