MDEV-4486: Allow to start old-style replication even if mysql.rpl_slave_state is unavailable
If the mysql.gtid_slave_pos table is not available, we cannot load nor update the current GTID position persistently. This can happen eg. after an upgrade, before mysql_upgrade_db is run, or if the table is InnoDB and the server is restarted without the InnoDB storage engine enabled. Before, replication always failed to start if the table was unavailable. With this patch, we try to continue with old-style replication, after suitable complaints in the error log. In strict mode, or if slave is configured to use GTID, slave still refuses to start.
This commit is contained in:
parent
dbe2c5060e
commit
03aa4876e1
@ -59,6 +59,57 @@ OK
|
||||
SELECT IF(@current_pos1=@current_pos2, "OK", CONCAT(@current_pos1, " != ", @current_pos2));
|
||||
IF(@current_pos1=@current_pos2, "OK", CONCAT(@current_pos1, " != ", @current_pos2))
|
||||
OK
|
||||
INSERT INTO t1 VALUES (6);
|
||||
include/start_slave.inc
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
*** MDEV-4486: Allow to start old-style replication even if mysql.gtid_slave_pos is unavailable
|
||||
include/stop_slave.inc
|
||||
CHANGE MASTER TO master_use_gtid= no;
|
||||
include/start_slave.inc
|
||||
INSERT INTO t1 VALUES (7);
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
include/stop_slave.inc
|
||||
SET sql_log_bin= 0;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
SET sql_log_bin= 1;
|
||||
SELECT * FROM mysql.gtid_slave_pos;
|
||||
ERROR 42000: Unknown storage engine 'InnoDB'
|
||||
SET sql_log_bin=0;
|
||||
call mtr.add_suppression("Failed to load slave replication state from table");
|
||||
call mtr.add_suppression("Unable to load replication GTID slave state");
|
||||
SET sql_log_bin=1;
|
||||
include/start_slave.inc
|
||||
Warnings:
|
||||
Error 1286 Unknown storage engine 'InnoDB'
|
||||
INSERT INTO t1 VALUES (8);
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
SET sql_log_bin= 0;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=MyISAM;
|
||||
SET sql_log_bin= 1;
|
||||
include/start_slave.inc
|
||||
DROP TABLE t1;
|
||||
include/rpl_end.inc
|
||||
|
@ -1,5 +1,6 @@
|
||||
--let $rpl_topology=1->2
|
||||
--source include/rpl_init.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
--echo *** Test normal shutdown/restart of slave server configured as a GTID slave. ***
|
||||
|
||||
@ -116,6 +117,80 @@ SET @slave_pos2= @@GLOBAL.gtid_slave_pos;
|
||||
SET @current_pos2= @@GLOBAL.gtid_current_pos;
|
||||
SELECT IF(@slave_pos1=@slave_pos2, "OK", CONCAT(@slave_pos1, " != ", @slave_pos2));
|
||||
SELECT IF(@current_pos1=@current_pos2, "OK", CONCAT(@current_pos1, " != ", @current_pos2));
|
||||
|
||||
--connection server_1
|
||||
INSERT INTO t1 VALUES (6);
|
||||
--save_master_pos
|
||||
|
||||
--connection server_2
|
||||
--source include/start_slave.inc
|
||||
--sync_with_master
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
|
||||
--echo *** MDEV-4486: Allow to start old-style replication even if mysql.gtid_slave_pos is unavailable
|
||||
|
||||
--connection server_2
|
||||
--source include/stop_slave.inc
|
||||
CHANGE MASTER TO master_use_gtid= no;
|
||||
--source include/start_slave.inc
|
||||
|
||||
--connection server_1
|
||||
INSERT INTO t1 VALUES (7);
|
||||
--save_master_pos
|
||||
|
||||
--connection server_2
|
||||
--sync_with_master
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
--source include/stop_slave.inc
|
||||
|
||||
SET sql_log_bin= 0;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
|
||||
SET sql_log_bin= 1;
|
||||
|
||||
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||
wait
|
||||
EOF
|
||||
--shutdown_server 30
|
||||
--source include/wait_until_disconnected.inc
|
||||
|
||||
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||
restart: --skip-slave-start=1 --skip-innodb
|
||||
EOF
|
||||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
--error ER_UNKNOWN_STORAGE_ENGINE
|
||||
SELECT * FROM mysql.gtid_slave_pos;
|
||||
SET sql_log_bin=0;
|
||||
call mtr.add_suppression("Failed to load slave replication state from table");
|
||||
call mtr.add_suppression("Unable to load replication GTID slave state");
|
||||
SET sql_log_bin=1;
|
||||
|
||||
--source include/start_slave.inc
|
||||
--connection server_1
|
||||
INSERT INTO t1 VALUES (8);
|
||||
--save_master_pos
|
||||
|
||||
--connection server_2
|
||||
--sync_with_master
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
|
||||
# Put things back as they were.
|
||||
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||
wait
|
||||
EOF
|
||||
--shutdown_server 30
|
||||
--source include/wait_until_disconnected.inc
|
||||
|
||||
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||
restart:
|
||||
EOF
|
||||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
SET sql_log_bin= 0;
|
||||
ALTER TABLE mysql.gtid_slave_pos ENGINE=MyISAM;
|
||||
SET sql_log_bin= 1;
|
||||
--source include/start_slave.inc
|
||||
|
||||
|
||||
|
@ -311,6 +311,18 @@ rpl_slave_state::record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
|
||||
ulonglong thd_saved_option= thd->variables.option_bits;
|
||||
Query_tables_list lex_backup;
|
||||
|
||||
if (unlikely(!loaded))
|
||||
{
|
||||
/*
|
||||
Probably the mysql.gtid_slave_pos table is missing (eg. upgrade) or
|
||||
corrupt.
|
||||
|
||||
We already complained loudly about this, but we can try to continue
|
||||
until the DBA fixes it.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!in_statement)
|
||||
mysql_reset_thd_for_next_command(thd, 0);
|
||||
|
||||
|
16
sql/slave.cc
16
sql/slave.cc
@ -3536,7 +3536,13 @@ pthread_handler_t handle_slave_io(void *arg)
|
||||
mi->report(ERROR_LEVEL, thd->stmt_da->sql_errno(),
|
||||
"Unable to load replication GTID slave state from mysql.%s: %s",
|
||||
rpl_gtid_slave_state_table_name.str, thd->stmt_da->message());
|
||||
goto err;
|
||||
/*
|
||||
If we are using old-style replication, we can continue, even though we
|
||||
then will not be able to record the GTIDs we receive. But if using GTID,
|
||||
we must give up.
|
||||
*/
|
||||
if (mi->using_gtid != Master_info::USE_GTID_NO || opt_gtid_strict_mode)
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
@ -4141,7 +4147,13 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME,
|
||||
rli->report(ERROR_LEVEL, thd->stmt_da->sql_errno(),
|
||||
"Unable to load replication GTID slave state from mysql.%s: %s",
|
||||
rpl_gtid_slave_state_table_name.str, thd->stmt_da->message());
|
||||
goto err;
|
||||
/*
|
||||
If we are using old-style replication, we can continue, even though we
|
||||
then will not be able to record the GTIDs we receive. But if using GTID,
|
||||
we must give up.
|
||||
*/
|
||||
if (mi->using_gtid != Master_info::USE_GTID_NO || opt_gtid_strict_mode)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* execute init_slave variable */
|
||||
|
Loading…
x
Reference in New Issue
Block a user