mirror of
https://github.com/MariaDB/server.git
synced 2025-09-10 11:30:17 +02: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>
218 lines
6.2 KiB
Text
218 lines
6.2 KiB
Text
#
|
|
# This test ensures that, when a GTID event is constructed by reading its
|
|
# content from a binlog file, the reader (e.g. replica, in this test) cannot
|
|
# read beyond the length of the GTID event. That is, we ensure that the
|
|
# structure indicated by its flags and extra_flags are consistent with the
|
|
# actual content of the event.
|
|
#
|
|
# To spoof a broken GTID log event, we use the DEBUG_DBUG mechanism to inject
|
|
# the master to write invalid GTID events for each flag. The transaction is
|
|
# given a commit id to ensure the event is not shorter than GTID_HEADER_LEN,
|
|
# which would result in zero padding up to GTID_HEADER_LEN.
|
|
#
|
|
#
|
|
# References:
|
|
# MDEV-33672: Gtid_log_event Construction from File Should Ensure Event
|
|
# Length When Using Extra Flags
|
|
#
|
|
|
|
--source include/have_debug.inc
|
|
|
|
# GTID event extra_flags are format independent
|
|
--source include/have_binlog_format_row.inc
|
|
--source include/have_innodb.inc
|
|
--source include/master-slave.inc
|
|
|
|
--echo #
|
|
--echo # Initialize test data
|
|
--connection master
|
|
create table t1 (a int) engine=innodb;
|
|
--source include/save_master_gtid.inc
|
|
set @@SESSION.debug_dbug= "+d,binlog_force_commit_id";
|
|
|
|
--connection slave
|
|
set SQL_LOG_BIN= 0;
|
|
call mtr.add_suppression('Found invalid event in binary log');
|
|
call mtr.add_suppression('Slave SQL.*Relay log read failure: Could not parse relay log event entry.* 1594');
|
|
set SQL_LOG_BIN= 1;
|
|
--source include/sync_with_master_gtid.inc
|
|
--source include/stop_slave.inc
|
|
--source include/start_slave.inc
|
|
--let $cid_ctr= 100
|
|
|
|
|
|
--echo #
|
|
--echo # Test FL_PREPARED_XA
|
|
--connection master
|
|
set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid";
|
|
--eval set @commit_id= $cid_ctr
|
|
|
|
XA START 'x1';
|
|
insert into t1 values (1);
|
|
XA END 'x1';
|
|
XA PREPARE 'x1';
|
|
set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid";
|
|
XA COMMIT 'x1';
|
|
--source include/save_master_gtid.inc
|
|
|
|
--echo # Waiting for slave to find invalid event..
|
|
--connection slave
|
|
let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE
|
|
source include/wait_for_slave_sql_error.inc;
|
|
STOP SLAVE IO_THREAD;
|
|
|
|
--echo # Reset master binlogs (as there is an invalid event) and slave state
|
|
--connection master
|
|
--source include/kill_binlog_dump_threads.inc
|
|
RESET MASTER;
|
|
--connection slave
|
|
RESET MASTER;
|
|
RESET SLAVE;
|
|
set @@global.gtid_slave_pos="";
|
|
--source include/start_slave.inc
|
|
|
|
|
|
--echo #
|
|
--echo # Test FL_COMPLETED_XA
|
|
--connection master
|
|
--inc $cid_ctr
|
|
--eval set @commit_id= $cid_ctr
|
|
XA START 'x1';
|
|
--let $next_val = `SELECT max(a)+1 FROM t1`
|
|
--eval insert into t1 values ($next_val)
|
|
XA END 'x1';
|
|
XA PREPARE 'x1';
|
|
set @@SESSION.debug_dbug= "+d,negate_xid_from_gtid";
|
|
XA COMMIT 'x1';
|
|
set @@SESSION.debug_dbug= "-d,negate_xid_from_gtid";
|
|
--source include/save_master_gtid.inc
|
|
|
|
--echo # Waiting for slave to find invalid event..
|
|
--connection slave
|
|
let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE
|
|
source include/wait_for_slave_sql_error.inc;
|
|
STOP SLAVE IO_THREAD;
|
|
|
|
--echo # Cleanup hanging XA PREPARE on slave
|
|
set statement SQL_LOG_BIN=0 for XA COMMIT 'x1';
|
|
|
|
--echo # Reset master binlogs (as there is an invalid event) and slave state
|
|
--connection master
|
|
--source include/kill_binlog_dump_threads.inc
|
|
RESET MASTER;
|
|
--connection slave
|
|
RESET MASTER;
|
|
RESET SLAVE;
|
|
set @@global.gtid_slave_pos="";
|
|
--source include/start_slave.inc
|
|
|
|
|
|
--echo #
|
|
--echo # Test Missing xid.data (but has format id and length description parts)
|
|
|
|
--connection master
|
|
--eval set @commit_id= $cid_ctr
|
|
|
|
XA START 'x1';
|
|
insert into t1 values (1);
|
|
XA END 'x1';
|
|
XA PREPARE 'x1';
|
|
set @@SESSION.debug_dbug= "+d,negate_xid_data_from_gtid";
|
|
XA COMMIT 'x1';
|
|
set @@SESSION.debug_dbug= "-d,negate_xid_data_from_gtid";
|
|
--source include/save_master_gtid.inc
|
|
|
|
--echo # Waiting for slave to find invalid event..
|
|
--connection slave
|
|
let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE
|
|
source include/wait_for_slave_sql_error.inc;
|
|
STOP SLAVE IO_THREAD;
|
|
|
|
--echo # Cleanup hanging XA PREPARE on slave
|
|
set statement SQL_LOG_BIN=0 for XA COMMIT 'x1';
|
|
|
|
--echo # Reset master binlogs (as there is an invalid event) and slave state
|
|
--connection master
|
|
--source include/kill_binlog_dump_threads.inc
|
|
RESET MASTER;
|
|
--connection slave
|
|
RESET MASTER;
|
|
RESET SLAVE;
|
|
set @@global.gtid_slave_pos="";
|
|
--source include/start_slave.inc
|
|
|
|
|
|
--echo #
|
|
--echo # Test FL_EXTRA_MULTI_ENGINE
|
|
--connection master
|
|
set @old_dbug= @@SESSION.debug_dbug;
|
|
set @@SESSION.debug_dbug= "+d,inject_fl_extra_multi_engine_into_gtid";
|
|
--inc $cid_ctr
|
|
--eval set @commit_id= $cid_ctr
|
|
--let $next_val = `SELECT max(a)+1 FROM t1`
|
|
--eval insert into t1 values ($next_val)
|
|
--source include/save_master_gtid.inc
|
|
set @@SESSION.debug_dbug=@old_dbug;
|
|
|
|
--connection slave
|
|
--echo # Waiting for slave to find invalid event..
|
|
let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE
|
|
source include/wait_for_slave_sql_error.inc;
|
|
STOP SLAVE IO_THREAD;
|
|
|
|
--echo # Reset master binlogs (as there is an invalid event) and slave state
|
|
--connection master
|
|
--source include/kill_binlog_dump_threads.inc
|
|
RESET MASTER;
|
|
|
|
--connection slave
|
|
RESET SLAVE;
|
|
RESET MASTER;
|
|
set @@global.gtid_slave_pos="";
|
|
--source include/start_slave.inc
|
|
|
|
|
|
--echo #
|
|
--echo # Test FL_COMMIT_ALTER
|
|
--connection master
|
|
set @old_dbug= @@SESSION.debug_dbug;
|
|
set @@SESSION.debug_dbug= "+d,negate_alter_fl_from_gtid";
|
|
set @old_alter_tp= @@SESSION.binlog_alter_two_phase;
|
|
set @@SESSION.binlog_alter_two_phase= 1;
|
|
alter table t1 add column (nc int);
|
|
--source include/save_master_gtid.inc
|
|
set @@SESSION.debug_dbug=@old_dbug;
|
|
set @@SESSION.binlog_alter_two_phase=@old_alter_tp;
|
|
|
|
--connection slave
|
|
--echo # Waiting for slave to find invalid event..
|
|
let $slave_sql_errno= 1594; # ER_SLAVE_RELAY_LOG_READ_FAILURE
|
|
source include/wait_for_slave_sql_error.inc;
|
|
STOP SLAVE IO_THREAD;
|
|
|
|
--echo # Reset master binlogs (as there is an invalid event) and slave state
|
|
--connection master
|
|
--source include/kill_binlog_dump_threads.inc
|
|
RESET MASTER;
|
|
|
|
--connection slave
|
|
# Just to keep tables consistent between master/slave
|
|
SET STATEMENT sql_log_bin=0 FOR alter table t1 add column (nc int);
|
|
RESET SLAVE;
|
|
RESET MASTER;
|
|
set @@global.gtid_slave_pos="";
|
|
--source include/start_slave.inc
|
|
|
|
|
|
--echo #
|
|
--echo # Cleanup
|
|
|
|
--connection master
|
|
drop table t1;
|
|
--source include/save_master_gtid.inc
|
|
|
|
--connection slave
|
|
--source include/sync_with_master_gtid.inc
|
|
|
|
--source include/rpl_end.inc
|
|
--echo # End of rpl_gtid_header_valid.test
|