--source include/have_innodb.inc --source include/have_log_bin.inc --source include/not_embedded.inc --echo # --echo # MDEV-41636: a failed sync of ddl_recovery.log after the engine change makes --echo # DROP TABLE / ALTER TABLE return an error although the DDL was applied, and an --echo # in-place ALTER is then missing from the binary log. --echo # Expected: a statement either fails with nothing applied and nothing logged, --echo # or succeeds, is applied and is logged. This test FAILS while the bug exists. --echo # (local verification only: needs strace + passwordless sudo) --echo # # Skip unless strace and passwordless sudo are available --perl my $ok = system("which strace >/dev/null 2>&1") == 0 && system("sudo -n true >/dev/null 2>&1") == 0; open(F, ">$ENV{MYSQLTEST_VARDIR}/tmp/mdev41636_skip.inc") or die $!; print F ($ok ? "" : "--skip needs strace and passwordless sudo\n"); close F; EOF --source $MYSQLTEST_VARDIR/tmp/mdev41636_skip.inc --let $failures= 0 --let $pid_file= `SELECT @@pid_file` --let $helper= $MYSQL_TEST_DIR/std_data/strace_inject.sh --let $ddl= $MYSQLTEST_VARDIR/mysqld.1/data/ddl_recovery.log --let $trace= $MYSQLTEST_VARDIR/tmp/mdev41636.trace CREATE TABLE t1 (id INT PRIMARY KEY, v INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1,1); --echo # --------------------------------------------------------------- --echo # DROP TABLE t3: EIO on the N-th fdatasync of ddl_recovery.log, N = 1..6 --echo # (the report used ENOSPC on the 1st; the error type does not matter here) --echo # --------------------------------------------------------------- --let $n= 1 while ($n < 7) { CREATE TABLE IF NOT EXISTS t3 LIKE t1; --let $g0= `SELECT @@gtid_binlog_pos` --exec INJECT_SYSCALLS=fdatasync INJECT_ACTION=error=EIO INJECT_WHEN=$n INJECT_PATH=$ddl sh $helper start $pid_file $trace --disable_abort_on_error DROP TABLE t3; --let $err= $mysql_errno --enable_abort_on_error --exec sh $helper stop $pid_file $trace --let $gone= `SELECT COUNT(*)=0 FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t3'` --let $g1= `SELECT @@gtid_binlog_pos` --let $logged= `SELECT '$g0' != '$g1'` --echo # DROP TABLE, EIO on fdatasync #$n: errno=$err dropped=$gone binlogged=$logged --let $bad= `SELECT $err != 0 AND $gone = 1` if ($bad) { --echo FAIL: DROP TABLE returned error $err although the table was dropped (fdatasync #$n) --inc $failures } --inc $n } --echo # --------------------------------------------------------------- --echo # ALTER TABLE t1 ADD COLUMN c1 INT (in-place): EIO on the N-th fdatasync, N = 1..6 --echo # (the report: the 5th sync, after the phase update DDL_ALTER_TABLE_PHASE_INPLACE_COPIED) --echo # --------------------------------------------------------------- --let $n= 1 while ($n < 7) { DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id INT PRIMARY KEY, v INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1,1); --let $g0= `SELECT @@gtid_binlog_pos` --exec INJECT_SYSCALLS=fdatasync INJECT_ACTION=error=EIO INJECT_WHEN=$n INJECT_PATH=$ddl sh $helper start $pid_file $trace --disable_abort_on_error ALTER TABLE t1 ADD COLUMN c1 INT, ALGORITHM=INPLACE; --let $err= $mysql_errno --enable_abort_on_error --exec sh $helper stop $pid_file $trace --let $applied= `SELECT COUNT(*) > 0 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1' AND COLUMN_NAME='c1'` --let $g1= `SELECT @@gtid_binlog_pos` --let $logged= `SELECT '$g0' != '$g1'` --echo # ADD COLUMN, EIO on fdatasync #$n: errno=$err column_exists=$applied binlogged=$logged --let $bad= `SELECT $err != 0 AND $applied = 1` if ($bad) { --echo FAIL: ALTER TABLE returned error $err although the column was added (fdatasync #$n) --inc $failures } --let $bad= `SELECT $applied = 1 AND $logged = 0` if ($bad) { --echo FAIL: ALTER TABLE was applied but is MISSING from the binary log (fdatasync #$n) --inc $failures } --inc $n } --echo # The column added by the failed ALTER must survive a restart consistently --source include/restart_mysqld.inc SHOW CREATE TABLE t1; --remove_file $trace DROP TABLE IF EXISTS t1, t3; if ($failures) { --die MDEV-41636 reproduced: $failures check(s) failed (false DDL failures / missing binlog events) } --echo # all checks passed