# ==== Purpose ==== # The test verifies attempt to recover by the semisync slave server whose # binlog is unsafe for truncation. # # ==== Implementation ==== # 2 binlog files are created with the 1st one destined to be the binlog # checkpoint file for recovery. # The final group of events is replication unsafe (myisam INSERT). # Therefore the semisync slave recovery may not. # # Steps: # 0 - Set max_binlog_size= 4096, to help an insert into a # transaction table 'ti' get binlog rotated while the # transaction won't be committed, being stopped at # a prior to commit debug_sync point # 1 - insert into a non-transactional 'tm' table completes with # binary logging as well # 2 - kill and attempt to restart the server as semisync slave that # must produce an expected unsafe-to-recover error # 3 - complete the test with a normal restart that successfully finds and # commits the transaction in doubt. # # ==== References ==== # # MDEV-21117: recovery for --rpl-semi-sync-slave-enabled server # --source include/have_innodb.inc --source include/have_debug_sync.inc --source include/have_binlog_format_row.inc SET @@global.max_binlog_size= 4096; call mtr.add_suppression("Table '.*tm' is marked as crashed and should be repaired"); call mtr.add_suppression("Got an error from unknown thread"); call mtr.add_suppression("Checking table: '.*tm'"); call mtr.add_suppression("Recovering table: '.*tm'"); call mtr.add_suppression("Cannot truncate the binary log to file"); call mtr.add_suppression("Crash recovery failed"); call mtr.add_suppression("Can.t init tc log"); call mtr.add_suppression("Aborting"); call mtr.add_suppression("Found 1 prepared transactions"); call mtr.add_suppression("mysqld: Table.*tm.*is marked as crashed"); call mtr.add_suppression("Checking table.*tm"); RESET MASTER; FLUSH LOGS; SET @@global.sync_binlog=1; CREATE TABLE ti (a INT PRIMARY KEY, b MEDIUMTEXT) ENGINE=Innodb; CREATE TABLE tm (f INT) ENGINE=MYISAM; --let $row_count = 5 --let $i = `select $row_count-2` --disable_query_log while ($i) { --eval INSERT INTO ti VALUES ($i, REPEAT("x", 1)) --dec $i } --enable_query_log INSERT INTO tm VALUES(1); connect(master1,localhost,root,,); connect(master2,localhost,root,,); connect(master3,localhost,root,,); --connection master1 # The 1st trx binlogs, rotate binlog and hold on before committing at engine SET DEBUG_SYNC= "commit_after_release_LOCK_after_binlog_sync SIGNAL master1_ready WAIT_FOR master1_go_never_arrives"; --send_eval INSERT INTO ti VALUES ($row_count - 1, REPEAT("x", 4100)) --connection master2 SET DEBUG_SYNC= "now WAIT_FOR master1_ready"; # The 2nd trx for recovery, it does not rotate binlog SET DEBUG_SYNC= "commit_before_get_LOCK_commit_ordered SIGNAL master2_ready WAIT_FOR master2_go_never_arrives"; --send_eval INSERT INTO ti VALUES ($row_count, REPEAT("x", 1)) --connection master3 SET DEBUG_SYNC= "now WAIT_FOR master2_ready"; SET DEBUG_SYNC= "commit_before_get_LOCK_after_binlog_sync SIGNAL master3_ready"; --send INSERT INTO tm VALUES (2) --connection default SET DEBUG_SYNC= "now WAIT_FOR master3_ready"; --echo # The gtid binlog state prior the crash must be restored at the end of the test; SELECT @@global.gtid_binlog_state; --source include/kill_mysqld.inc # # Server restarts # --echo # Failed restart as the semisync slave --error 1 --exec $MYSQLD_LAST_CMD --rpl-semi-sync-slave-enabled=1 >> $MYSQLTEST_VARDIR/log/mysqld.1.err 2>&1 --echo # Normal restart --source include/start_mysqld.inc # Check error log for correct messages. let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err; --let SEARCH_FILE=$log_error_ --let SEARCH_PATTERN=Cannot truncate the binary log to file --source include/search_pattern_in_file.inc --echo # Proof that the in-doubt transactions are recovered by the 2nd normal server restart --eval SELECT COUNT(*) = $row_count as 'True' FROM ti # myisam table may require repair (which is not tested here) --disable_warnings SELECT COUNT(*) <= 1 FROM tm; --enable_warnings --echo # The gtid binlog state prior the crash is restored now SELECT @@GLOBAL.gtid_binlog_state; SELECT @@GLOBAL.gtid_binlog_pos; --echo # Cleanup DROP TABLE ti, tm; --echo End of test