1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-21 06:21:35 +03:00
Files
mariadb/mysql-test/suite/rpl/t/rpl_corruption.test
unknown 54fcd3b88e Another attempt at fixing the rare random failures of rpl_corruption
The previous patch partially fixed things by waiting for the old dump thread
on the master to exit before injecting the DBUG error. This prevents the error
injection going to the wrong thread.

However, there is still the problem that the old dump thread may never exit,
causing the wait to time out. This happens if the dump thread manages to write
all events down the socket before the socket is closed by the slave. The
master dump thread only checks for slave gone when writing a new event, so if
no new events are generated, old dump threads can hang around forever on the
master after the slave disconnects.

Fix by explicitly killing the old dump thread if it is still around.
2011-06-14 15:21:54 +02:00

166 lines
5.5 KiB
Plaintext

############################################################
# Purpose: WL#5064 Testing with corrupted events.
# The test emulates the corruption at the vary stages
# of replication:
# - in binlog file
# - in network
# - in relay log
############################################################
#
# The tests intensively utilize @@global.debug. Note,
# Bug#11765758 - 58754,
# @@global.debug is read by the slave threads through dbug-interface.
# Hence, before a client thread set @@global.debug we have to ensure that:
# (a) the slave threads are stopped, or (b) the slave threads are in
# sync and waiting.
--source include/have_debug.inc
--source include/master-slave.inc
# Block legal errors for MTR
call mtr.add_suppression('Found invalid event in binary log');
call mtr.add_suppression('Slave I/O: Relay log write failure: could not queue event from master');
call mtr.add_suppression('event read from binlog did not pass crc check');
call mtr.add_suppression('Replication event checksum verification failed');
call mtr.add_suppression('Event crc check failed! Most likely there is event corruption');
call mtr.add_suppression('Slave SQL: Error initializing relay log position: I/O error reading event at position .*, Error_code: 1593');
SET @old_master_verify_checksum = @@master_verify_checksum;
# Creating test table/data and set corruption position for testing
--echo # 1. Creating test table/data and set corruption position for testing
--connection master
--echo * insert/update/delete rows in table t1 *
# Corruption algorithm modifies only the first event and
# then will be reset. To avoid checking always the first event
# from binlog (usually it is FD) we randomly execute different
# statements and set position for corruption inside events.
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b VARCHAR(10), c VARCHAR(100));
--disable_query_log
let $i=`SELECT 3+CEILING(10*RAND())`;
let $j=1;
let $pos=0;
while ($i) {
eval INSERT INTO t1 VALUES ($j, 'a', NULL);
if (`SELECT RAND() > 0.7`)
{
eval UPDATE t1 SET c = REPEAT('a', 20) WHERE a = $j;
}
if (`SELECT RAND() > 0.8`)
{
eval DELETE FROM t1 WHERE a = $j;
}
if (!$pos) {
let $pos= query_get_value(SHOW MASTER STATUS, Position, 1);
--sync_slave_with_master
--source include/stop_slave.inc
--disable_query_log
--connection master
}
dec $i;
inc $j;
}
--enable_query_log
# Emulate corruption in binlog file when SHOW BINLOG EVENTS is executing
--echo # 2. Corruption in master binlog and SHOW BINLOG EVENTS
SET GLOBAL debug="+d,corrupt_read_log_event_char";
--echo SHOW BINLOG EVENTS;
--disable_query_log
send_eval SHOW BINLOG EVENTS FROM $pos;
--enable_query_log
--error ER_ERROR_WHEN_EXECUTING_COMMAND
reap;
SET GLOBAL debug="-d,corrupt_read_log_event_char";
# Emulate corruption on master with crc checking on master
--echo # 3. Master read a corrupted event from binlog and send the error to slave
# We have a rare but nasty potential race here: if the dump thread on
# the master for the _old_ slave connection has not yet discovered
# that the slave has disconnected, we will inject the corrupt event on
# the wrong connection, and the test will fail
# (+d,corrupt_read_log_event2 corrupts only one event).
# So kill any lingering dump thread (we need to kill; otherwise dump thread
# could manage to send all events down the socket before seeing it close, and
# hang forever waiting for new binlog events to be created).
let $id= `select id from information_schema.processlist where command = "Binlog Dump"`;
if ($id)
{
--disable_query_log
--error 0,1094
eval kill $id;
--enable_query_log
}
let $wait_condition=
SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE command = 'Binlog Dump';
--source include/wait_condition.inc
SET GLOBAL debug="+d,corrupt_read_log_event2";
--connection slave
START SLAVE IO_THREAD;
let $slave_io_errno= 1236;
--source include/wait_for_slave_io_error.inc
--connection master
SET GLOBAL debug="-d,corrupt_read_log_event2";
# Emulate corruption on master without crc checking on master
--echo # 4. Master read a corrupted event from binlog and send it to slave
--connection master
SET GLOBAL master_verify_checksum=0;
SET GLOBAL debug="+d,corrupt_read_log_event2";
--connection slave
START SLAVE IO_THREAD;
let $slave_io_errno= 1595,1722;
--source include/wait_for_slave_io_error.inc
--connection master
SET GLOBAL debug="-d,corrupt_read_log_event2";
SET GLOBAL debug= "";
SET GLOBAL master_verify_checksum=1;
# Emulate corruption in network
--echo # 5. Slave. Corruption in network
--connection slave
SET GLOBAL debug="+d,corrupt_queue_event";
START SLAVE IO_THREAD;
let $slave_io_errno= 1595,1722;
--source include/wait_for_slave_io_error.inc
SET GLOBAL debug="-d,corrupt_queue_event";
# Emulate corruption in relay log
--echo # 6. Slave. Corruption in relay log
SET GLOBAL debug="+d,corrupt_read_log_event_char";
START SLAVE SQL_THREAD;
let $slave_sql_errno= 1593;
--source include/wait_for_slave_sql_error.inc
SET GLOBAL debug="-d,corrupt_read_log_event_char";
SET GLOBAL debug= "";
# Start normal replication and compare same table on master
# and slave
--echo # 7. Seek diff for tables on master and slave
--connection slave
--source include/start_slave.inc
--connection master
--sync_slave_with_master
let $diff_tables= master:test.t1, slave:test.t1;
--source include/diff_tables.inc
# Clean up
--echo # 8. Clean up
--connection master
SET GLOBAL debug= "";
SET GLOBAL master_verify_checksum = @old_master_verify_checksum;
DROP TABLE t1;
--sync_slave_with_master
SET GLOBAL debug= "";
--source include/rpl_end.inc