mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
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.
This commit is contained in:
parent
e0c8d729a2
commit
312219cc63
11 changed files with 213 additions and 8 deletions
|
@ -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);
|
||||
|
|
6
mysql-test/std_data/new-format-relay-log-win.info
Normal file
6
mysql-test/std_data/new-format-relay-log-win.info
Normal file
|
@ -0,0 +1,6 @@
|
|||
5
|
||||
.\slave-relay-bin.000001
|
||||
4
|
||||
|
||||
0
|
||||
0
|
6
mysql-test/std_data/new-format-relay-log.info
Normal file
6
mysql-test/std_data/new-format-relay-log.info
Normal file
|
@ -0,0 +1,6 @@
|
|||
5
|
||||
./slave-relay-bin.000001
|
||||
4
|
||||
|
||||
0
|
||||
0
|
4
mysql-test/std_data/old-format-relay-log-win.info
Normal file
4
mysql-test/std_data/old-format-relay-log-win.info
Normal file
|
@ -0,0 +1,4 @@
|
|||
.\slave-relay-bin.000001
|
||||
4
|
||||
|
||||
0
|
4
mysql-test/std_data/old-format-relay-log.info
Normal file
4
mysql-test/std_data/old-format-relay-log.info
Normal file
|
@ -0,0 +1,4 @@
|
|||
./slave-relay-bin.000001
|
||||
4
|
||||
|
||||
0
|
14
mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result
Normal file
14
mysql-test/suite/rpl/r/rpl_read_new_relay_log_info.result
Normal file
|
@ -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
|
14
mysql-test/suite/rpl/r/rpl_read_old_relay_log_info.result
Normal file
14
mysql-test/suite/rpl/r/rpl_read_old_relay_log_info.result
Normal file
|
@ -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
|
43
mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test
Normal file
43
mysql-test/suite/rpl/t/rpl_read_new_relay_log_info.test
Normal file
|
@ -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
|
44
mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test
Normal file
44
mysql-test/suite/rpl/t/rpl_read_old_relay_log_info.test
Normal file
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue