Commit 312219cc authored by Kristian Nielsen's avatar Kristian Nielsen

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.
parent e0c8d729
......@@ -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);
......
5
./slave-relay-bin.000001
4
0
0
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
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
# ==== 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
# ==== 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
......@@ -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;
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment