# # This include file is used by more than one test suite # (currently rpl and binlog_encryption). # Please check all dependent tests after modifying it # ############################################################ # 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.* 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 @saved_dbug = @@global.debug_dbug; SET @@global.debug_dbug="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_dbug=@saved_dbug; # 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_dbug="d,corrupt_read_log_event2_set"; --connection slave START SLAVE IO_THREAD; let $slave_io_errno= 1236; --let $slave_timeout= 10 --source include/wait_for_slave_io_error.inc --connection master SET @@global.debug_dbug=@saved_dbug; # 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_dbug="d,corrupt_read_log_event2_set"; --connection slave START SLAVE IO_THREAD; # When the checksum error is detected, the slave sets error code 1743 # (ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE) in queue_event(), then immediately # sets error 1595 (ER_SLAVE_RELAY_LOG_WRITE_FAILURE) in handle_slave_io(). # So we usually get 1595, but it is occasionally possible to get 1743. let $slave_io_errno= 1595,1743; # ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE --source include/wait_for_slave_io_error.inc --connection master SET @@global.debug_dbug=@saved_dbug; SET GLOBAL master_verify_checksum=1; # Emulate corruption in network --echo # 5. Slave. Corruption in network --connection slave SET @saved_dbug_slave = @@GLOBAL.debug_dbug; SET @@global.debug_dbug="d,corrupt_queue_event"; START SLAVE IO_THREAD; let $slave_io_errno= 1595,1743; # ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE --source include/wait_for_slave_io_error.inc SET @@global.debug_dbug=@saved_dbug_slave; # Emulate corruption in relay log --echo # 6. Slave. Corruption in relay log SET @@global.debug_dbug="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_dbug=@saved_dbug_slave; # 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_dbug = @saved_dbug; SET GLOBAL master_verify_checksum = @old_master_verify_checksum; DROP TABLE t1; --sync_slave_with_master --source include/rpl_end.inc