mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
This is actually an existing problem in the old binlog implementation, and this patch is applicable to old binlog also. The problem is that RESET MASTER can run concurrently with binlog dump threads / connected slaves. This will remove the binlog from under the feet of the reader, which can cause all sorts of strange behaviour. This patch fixes the problem by disallowing to run RESET MASTER when dump threads (or other RESET MASTER or SHOW BINARY LOGS) are running. An error is thrown in this case, user must stop slaves and/or kill dump threads to make the RESET MASTER go through. A slave that connects in the middle of RESET MASTER will wait for it to complete. Fix a lot of test cases to kill any lingering dump threads before doing RESET MASTER, mostly just by sourcing include/kill_binlog_dump_threads.inc. Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
177 lines
5.6 KiB
Plaintext
177 lines
5.6 KiB
Plaintext
# Testing master to slave heartbeat protocol
|
|
#
|
|
# Including:
|
|
# - user interface, grammar, checking the range and warnings about
|
|
# unreasonable values for the heartbeat period;
|
|
# - no rotation of relay log if heartbeat is less that slave_net_timeout
|
|
# - SHOW STATUS like 'Slave_received_heartbeats' action
|
|
# - SHOW STATUS like 'Slave_heartbeat_period' report
|
|
|
|
-- source include/have_log_bin.inc
|
|
-- source include/master-slave.inc
|
|
|
|
connection slave;
|
|
-- source include/stop_slave.inc
|
|
|
|
connection master;
|
|
--source include/kill_binlog_dump_threads.inc
|
|
reset master;
|
|
|
|
connection slave;
|
|
set @restore_slave_net_timeout= @@global.slave_net_timeout;
|
|
--disable_warnings
|
|
set @@global.slave_net_timeout= 10;
|
|
--enable_warnings
|
|
|
|
--enable_prepare_warnings
|
|
###
|
|
### Checking the range
|
|
###
|
|
|
|
#
|
|
# default period slave_net_timeout/2
|
|
#
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root';
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
#
|
|
# the max for the period is ULONG_MAX/1000; an attempt to exceed it is denied
|
|
#
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 4294968;
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
#
|
|
# the min value for the period is 1 millisecond an attempt to assign a
|
|
# lesser will be warned with treating the value as zero
|
|
#
|
|
connection slave;
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
### 5.1 mtr does not have --warning ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 0.0009999;
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
#
|
|
# the actual max and min must be accepted
|
|
#
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 4294967;
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 0.001;
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
reset slave;
|
|
|
|
#
|
|
# A warning if period greater than slave_net_timeout
|
|
#
|
|
set @@global.slave_net_timeout= 5;
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 5.001;
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
reset slave;
|
|
|
|
#
|
|
# A warning if slave_net_timeout is set to less than the current HB period
|
|
#
|
|
set @@global.slave_net_timeout= 5;
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 4;
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
set @@global.slave_net_timeout= 3 /* must be a warning */;
|
|
|
|
reset slave;
|
|
|
|
|
|
###
|
|
### checking no rotation
|
|
###
|
|
|
|
connection master;
|
|
--disable_warnings
|
|
drop table if exists t1;
|
|
--enable_warnings
|
|
#
|
|
# Even though master_heartbeat_period= 0.5 is 20 times less than
|
|
# @@global.slave_net_timeout= 10 in some circumstances master will
|
|
# not be able to send any heartbeat during the slave's net timeout
|
|
# and slave's relay log will rotate.
|
|
# The probability for such a scenario is pretty small so the following
|
|
# part is almost deterministic.
|
|
#
|
|
|
|
connection slave;
|
|
set @@global.slave_net_timeout= 10;
|
|
--replace_result $MASTER_MYPORT MASTER_PORT
|
|
# no error this time but rather a warning
|
|
eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_ssl_verify_server_cert=0, master_heartbeat_period= 0.5;
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
start slave;
|
|
|
|
connection master;
|
|
create table t1 (f1 int);
|
|
|
|
#connection slave;
|
|
sync_slave_with_master;
|
|
let $slave_param= Relay_Log_File;
|
|
let $slave_param_value= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1);
|
|
|
|
# there is an explicit sleep lasting longer than slave_net_timeout
|
|
# to ensure that nothing will come to slave from master for that period.
|
|
# That would cause reconnecting and relaylog rotation w/o the fix i.e
|
|
# without a heartbeat received.
|
|
|
|
real_sleep 15;
|
|
|
|
# check (compare with the previous show's results) that no rotation happened
|
|
source include/check_slave_param.inc;
|
|
|
|
###
|
|
### SHOW STATUS like 'Slave_heartbeat_period' and 'Slave_received_heartbeats'
|
|
###
|
|
|
|
--query_vertical show status like 'Slave_heartbeat_period';
|
|
|
|
#
|
|
# proof that there has been received at least one heartbeat;
|
|
# The exact number of received heartbeat is an indeterministic value
|
|
# and therefore it's not recorded into results.
|
|
#
|
|
|
|
let $slave_wait_param_counter= 300;
|
|
let $slave_value= query_get_value("SHOW STATUS like 'Slave_received_heartbeats'", Value, 1);
|
|
# Checking the fact that at least one heartbeat is received
|
|
while (!$slave_value)
|
|
{
|
|
dec $slave_wait_param_counter;
|
|
if (!$slave_wait_param_counter)
|
|
{
|
|
--echo ERROR: failed while waiting for slave parameter $slave_param: $slave_param_value
|
|
query_vertical show slave status;
|
|
SHOW STATUS like 'Slave_received_heartbeats';
|
|
exit;
|
|
}
|
|
sleep 0.1;
|
|
let $slave_value= query_get_value("SHOW STATUS like 'Slave_received_heartbeats'", Value, 1);
|
|
}
|
|
--echo A heartbeat has been received by the slave
|
|
# cleanup
|
|
|
|
connection master;
|
|
drop table t1;
|
|
|
|
#connection slave;
|
|
sync_slave_with_master;
|
|
set @@global.slave_net_timeout= @restore_slave_net_timeout;
|
|
|
|
--disable_prepare_warnings
|
|
|
|
--source include/rpl_end.inc
|
|
--echo End of tests
|