summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Nielsen <knielsen@knielsen-hq.org>2014-06-24 14:43:08 +0200
committerKristian Nielsen <knielsen@knielsen-hq.org>2014-06-24 14:43:08 +0200
commit312219cc63fd49734b3369cc41cdc0f5cf2aaa7f (patch)
tree907dfdf08ea24e93abb755227638a18aa428baab
parente0c8d729a27ae3a8a1a6c5e6e64f0380381f53d5 (diff)
downloadmariadb-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.cc4
-rw-r--r--mysql-test/std_data/new-format-relay-log-win.info6
-rw-r--r--mysql-test/std_data/new-format-relay-log.info6
-rw-r--r--mysql-test/std_data/old-format-relay-log-win.info4
-rw-r--r--mysql-test/std_data/old-format-relay-log.info4
-rw-r--r--mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result14
-rw-r--r--mysql-test/suite/rpl/r/rpl_read_old_relay_log_info.result14
-rw-r--r--mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test43
-rw-r--r--mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test44
-rw-r--r--sql/rpl_rli.cc74
-rw-r--r--sql/rpl_rli.h6
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