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, "") || - 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)) + &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(&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