--source include/have_maria.inc --source include/have_sequence.inc --source include/not_embedded.inc --echo # --echo # MDEV-41706: Aria: a failed data-page write during FLUSH TABLES drops the dirty --echo # page; committed UPDATEs on a TRANSACTIONAL=1 table are silently lost. --echo # Expected: the committed UPDATE stays visible. 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/mdev41706_skip.inc") or die $!; print F ($ok ? "" : "--skip needs strace and passwordless sudo\n"); close F; EOF --source $MYSQLTEST_VARDIR/tmp/mdev41706_skip.inc # The bug makes the table "crashed" and Aria repairs it; keep MTR's log scan quiet call mtr.add_suppression("marked as crashed"); call mtr.add_suppression("Got error '145"); call mtr.add_suppression("Recovering table"); call mtr.add_suppression("Checking table"); call mtr.add_suppression("Aria engine"); --let $failures= 0 --let $pid_file= `SELECT @@pid_file` --let $helper= $MYSQL_TEST_DIR/std_data/strace_inject.sh --let $datadir= $MYSQLTEST_VARDIR/mysqld.1/data/test --let $trace1= $MYSQLTEST_VARDIR/tmp/mdev41706_flush.trace --let $trace2= $MYSQLTEST_VARDIR/tmp/mdev41706_rename.trace --echo # --------------------------------------------------------------- --echo # Case 1: FLUSH TABLES with EIO on the first write to t1.MAD --echo # --------------------------------------------------------------- CREATE TABLE t1 (id INT PRIMARY KEY, v VARCHAR(200)) ENGINE=Aria TRANSACTIONAL=1; INSERT INTO t1 SELECT seq, CONCAT('old-', seq, '-', REPEAT('x',150)) FROM seq_1_to_2000; FLUSH TABLES; UPDATE t1 SET v=CONCAT('new-', id, '-', REPEAT('y',150)); SELECT COUNT(*) AS cnt, SUM(v LIKE 'new-%') AS new_rows FROM t1; --exec INJECT_SYSCALLS=pwrite64 INJECT_PATH=$datadir/t1.MAD sh $helper start $pid_file $trace1 --disable_abort_on_error FLUSH TABLES; --echo FLUSH TABLES errno: $mysql_errno (0 = reported OK) --enable_abort_on_error --exec sh $helper stop $pid_file $trace1 --echo # injected writes to t1.MAD (must be 1): --exec grep -c INJECTED $trace1 --echo # Rows after the failed flush (the UPDATE was committed; old_rows must be 0): SELECT COUNT(*) AS cnt, COALESCE(SUM(v LIKE 'old-%'),0) AS old_rows FROM t1; --let $old= `SELECT COALESCE(SUM(v LIKE 'old-%'),0) FROM t1` if ($old) { --echo FAIL: $old committed row(s) of t1 show the old version after FLUSH TABLES --inc $failures } --echo # After a restart: --source include/restart_mysqld.inc SELECT COALESCE(SUM(v LIKE 'new-%'),0) AS new_rows, COALESCE(SUM(v LIKE 'old-%'),0) AS old_rows FROM t1; --let $old= `SELECT COALESCE(SUM(v LIKE 'old-%'),0) FROM t1` if ($old) { --echo FAIL: $old committed row(s) of t1 still show the old version after the restart --inc $failures } CHECK TABLE t1 EXTENDED; --echo # --------------------------------------------------------------- --echo # Case 2: RENAME TABLE (flushes the table) with EIO on the first write to t2.MAD --echo # --------------------------------------------------------------- CREATE TABLE t2 (id INT PRIMARY KEY, v VARCHAR(200)) ENGINE=Aria TRANSACTIONAL=1; INSERT INTO t2 SELECT seq, CONCAT('old-', seq, '-', REPEAT('x',150)) FROM seq_1_to_2000; FLUSH TABLES; UPDATE t2 SET v=CONCAT('new-', id, '-', REPEAT('y',150)); --let $pid_file= `SELECT @@pid_file` --exec INJECT_SYSCALLS=pwrite64 INJECT_PATH=$datadir/t2.MAD sh $helper start $pid_file $trace2 --disable_abort_on_error RENAME TABLE t2 TO t7; --echo RENAME TABLE errno: $mysql_errno (0 = reported OK) --enable_abort_on_error --exec sh $helper stop $pid_file $trace2 --echo # injected writes to t2.MAD (must be 1): --exec grep -c INJECTED $trace2 --let $tn= `SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='test' AND TABLE_NAME IN ('t2','t7')` --let $old= `SELECT COALESCE(SUM(v LIKE 'old-%'),0) FROM $tn` --echo # old-version rows in the renamed table (must be 0): $old if ($old) { --echo FAIL: $old committed row(s) show the old version after RENAME TABLE --inc $failures } --remove_file $trace1 --remove_file $trace2 DROP TABLE IF EXISTS t1, t2, t7; if ($failures) { --die MDEV-41706 reproduced: $failures check(s) failed (committed Aria updates lost after a failed page write) } --echo # all checks passed