mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-4650: show variables; ERROR 1946 (HY000): Failed to load replication slave GTID position
The bug was that if mysql.slave_gtid_pos was missing, operations on variables gtid_slave_pos, gtid_binlog_pos, and gtid_current_pos would fail, and continue to fail even after the table was fixed, until server restart. Now setting the variables retry loading the table, succeeding if it has been restored. And querying the variables when the table is not there acts as if the table was there and was empty. Also, attempt to fix a race in the rpl.rpl_gtid_basic test case.
This commit is contained in:
@ -155,5 +155,31 @@ SELECT domain_id, COUNT(*) FROM mysql.gtid_slave_pos GROUP BY domain_id;
|
||||
domain_id COUNT(*)
|
||||
0 2
|
||||
1 2
|
||||
*** MDEV-4650: show variables; ERROR 1946 (HY000): Failed to load replication slave GTID position ***
|
||||
SET sql_log_bin=0;
|
||||
RENAME TABLE mysql.gtid_slave_pos TO mysql.gtid_slave_pos_old;
|
||||
SET sql_log_bin=1;
|
||||
SHOW VARIABLES;
|
||||
SHOW VARIABLES LIKE 'gtid_slave_pos';
|
||||
Variable_name Value
|
||||
gtid_slave_pos
|
||||
SET GLOBAL gtid_slave_pos = '0-1-2';
|
||||
Got one of the listed errors
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Error 1146 Table 'mysql.gtid_slave_pos' doesn't exist
|
||||
Error 1946 Failed to load replication slave GTID position from table mysql.gtid_slave_pos
|
||||
SET sql_log_bin=0;
|
||||
RENAME TABLE mysql.gtid_slave_pos_old TO mysql.gtid_slave_pos;
|
||||
CALL mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos");
|
||||
SET sql_log_bin=1;
|
||||
SHOW VARIABLES LIKE 'gtid_slave_pos';
|
||||
Variable_name Value
|
||||
gtid_slave_pos
|
||||
SET GLOBAL gtid_slave_pos = '0-1-2';
|
||||
SHOW VARIABLES LIKE 'gtid_slave_pos';
|
||||
Variable_name Value
|
||||
gtid_slave_pos 0-1-2
|
||||
include/start_slave.inc
|
||||
DROP TABLE t1;
|
||||
include/rpl_end.inc
|
||||
|
@ -191,11 +191,15 @@ SET GLOBAL gtid_binlog_state = @old_state;
|
||||
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
--save_master_pos
|
||||
--let $master_pos= `SELECT @@GLOBAL.gtid_binlog_pos`
|
||||
|
||||
--connection server_2
|
||||
--source include/start_slave.inc
|
||||
--sync_with_master
|
||||
# We cannot just use sync_with_master as we've done RESET MASTER, so
|
||||
# slave old-style position is wrong.
|
||||
# So sync on gtid position instead.
|
||||
--let $wait_condition= SELECT @@GLOBAL.gtid_binlog_pos = '$master_pos'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
|
@ -273,6 +273,57 @@ INSERT INTO t1 VALUES (13);
|
||||
SELECT domain_id, COUNT(*) FROM mysql.gtid_slave_pos GROUP BY domain_id;
|
||||
|
||||
|
||||
--echo *** MDEV-4650: show variables; ERROR 1946 (HY000): Failed to load replication slave GTID position ***
|
||||
|
||||
--connection server_2
|
||||
SET sql_log_bin=0;
|
||||
--let $old_pos= `SELECT @@GLOBAL.gtid_slave_pos`
|
||||
RENAME TABLE mysql.gtid_slave_pos TO mysql.gtid_slave_pos_old;
|
||||
SET sql_log_bin=1;
|
||||
|
||||
--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||
wait
|
||||
EOF
|
||||
--shutdown_server 30
|
||||
--source include/wait_until_disconnected.inc
|
||||
|
||||
# Let the slave mysqld server start again.
|
||||
--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||
restart
|
||||
EOF
|
||||
|
||||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
--disable_result_log
|
||||
SHOW VARIABLES;
|
||||
--enable_result_log
|
||||
SHOW VARIABLES LIKE 'gtid_slave_pos';
|
||||
--error ER_CANNOT_LOAD_SLAVE_GTID_STATE,ER_NO_SUCH_TABLE
|
||||
SET GLOBAL gtid_slave_pos = '0-1-2';
|
||||
SHOW WARNINGS;
|
||||
|
||||
# Restore things.
|
||||
|
||||
SET sql_log_bin=0;
|
||||
RENAME TABLE mysql.gtid_slave_pos_old TO mysql.gtid_slave_pos;
|
||||
CALL mtr.add_suppression("Failed to load slave replication state from table mysql.gtid_slave_pos");
|
||||
SET sql_log_bin=1;
|
||||
|
||||
SHOW VARIABLES LIKE 'gtid_slave_pos';
|
||||
SET GLOBAL gtid_slave_pos = '0-1-2';
|
||||
SHOW VARIABLES LIKE 'gtid_slave_pos';
|
||||
|
||||
# Don't let .result file depend on old state of gtid_slave_pos
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
eval SET GLOBAL gtid_slave_pos = '$old_pos';
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
|
||||
--source include/start_slave.inc
|
||||
|
||||
|
||||
--connection server_1
|
||||
DROP TABLE t1;
|
||||
|
||||
|
@ -1282,12 +1282,6 @@ Sys_var_gtid_binlog_pos::global_value_ptr(THD *thd, LEX_STRING *base)
|
||||
String str(buf, sizeof(buf), system_charset_info);
|
||||
char *p;
|
||||
|
||||
if (!rpl_global_gtid_slave_state.loaded)
|
||||
{
|
||||
my_error(ER_CANNOT_LOAD_SLAVE_GTID_STATE, MYF(0), "mysql",
|
||||
rpl_gtid_slave_state_table_name.str);
|
||||
return NULL;
|
||||
}
|
||||
str.length(0);
|
||||
if ((opt_bin_log && mysql_bin_log.append_state_pos(&str)) ||
|
||||
!(p= thd->strmake(str.ptr(), str.length())))
|
||||
@ -1316,7 +1310,17 @@ Sys_var_gtid_current_pos::global_value_ptr(THD *thd, LEX_STRING *base)
|
||||
char *p;
|
||||
|
||||
str.length(0);
|
||||
if (rpl_append_gtid_state(&str, true) ||
|
||||
|
||||
/*
|
||||
If the mysql.rpl_slave_pos table could not be loaded, then we cannot
|
||||
easily automatically try to reload it here - we may be inside a statement
|
||||
that already has tables locked and so opening more tables is problematic.
|
||||
|
||||
But if the table is not loaded (eg. missing mysql_upgrade_db or some such),
|
||||
then the slave state must be empty anyway.
|
||||
*/
|
||||
if ((rpl_global_gtid_slave_state.loaded &&
|
||||
rpl_append_gtid_state(&str, true)) ||
|
||||
!(p= thd->strmake(str.ptr(), str.length())))
|
||||
{
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
||||
@ -1335,7 +1339,7 @@ Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
|
||||
|
||||
DBUG_ASSERT(var->type == OPT_GLOBAL);
|
||||
|
||||
if (!rpl_global_gtid_slave_state.loaded)
|
||||
if (rpl_load_gtid_slave_state(thd))
|
||||
{
|
||||
my_error(ER_CANNOT_LOAD_SLAVE_GTID_STATE, MYF(0), "mysql",
|
||||
rpl_gtid_slave_state_table_name.str);
|
||||
@ -1400,15 +1404,17 @@ Sys_var_gtid_slave_pos::global_value_ptr(THD *thd, LEX_STRING *base)
|
||||
String str;
|
||||
char *p;
|
||||
|
||||
if (!rpl_global_gtid_slave_state.loaded)
|
||||
{
|
||||
my_error(ER_CANNOT_LOAD_SLAVE_GTID_STATE, MYF(0), "mysql",
|
||||
rpl_gtid_slave_state_table_name.str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str.length(0);
|
||||
if (rpl_append_gtid_state(&str, false) ||
|
||||
/*
|
||||
If the mysql.rpl_slave_pos table could not be loaded, then we cannot
|
||||
easily automatically try to reload it here - we may be inside a statement
|
||||
that already has tables locked and so opening more tables is problematic.
|
||||
|
||||
But if the table is not loaded (eg. missing mysql_upgrade_db or some such),
|
||||
then the slave state must be empty anyway.
|
||||
*/
|
||||
if ((rpl_global_gtid_slave_state.loaded &&
|
||||
rpl_append_gtid_state(&str, false)) ||
|
||||
!(p= thd->strmake(str.ptr(), str.length())))
|
||||
{
|
||||
my_error(ER_OUT_OF_RESOURCES, MYF(0));
|
||||
|
Reference in New Issue
Block a user