1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
# ==== 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 --init-rpl-role=SLAVE >> $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
|