--source include/have_innodb.inc --source include/not_embedded.inc --echo # --echo # MDEV-41707: failed unlink of #sql-backup tablespace after a copying ALTER --echo # leaves an orphan; later copying ALTERs on the same connection fail. --echo # Expected: later ALTERs succeed, no orphan stays. This test FAILS while the bug exists. --echo # (local verification only: needs strace + passwordless sudo) --echo # --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/mdev41707_skip.inc") or die $!; print F ($ok ? "" : "--skip needs strace and passwordless sudo\n"); close F; EOF --source $MYSQLTEST_VARDIR/tmp/mdev41707_skip.inc call mtr.add_suppression("InnoDB: File .*: 'delete' returned OS error"); call mtr.add_suppression("InnoDB: Cannot rename .* because the target file exists"); call mtr.add_suppression("sql-backup"); --let $failures= 0 --let $pid_file= `SELECT @@pid_file` --let $helper= $MYSQL_TEST_DIR/std_data/strace_inject.sh --let $trace= $MYSQLTEST_VARDIR/tmp/mdev41707.trace --let $datadir= $MYSQLTEST_VARDIR/mysqld.1/data/test CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1,1),(2,2); CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; --echo # Step 1: copying ALTER with EIO injected on the first unlink() --exec INJECT_SYSCALLS=unlink sh $helper start $pid_file $trace ALTER TABLE t1 MODIFY b BIGINT, ALGORITHM=COPY; SHOW WARNINGS; --exec sh $helper stop $pid_file $trace --echo # injected unlink (must be on the #sql-backup .ibd): --replace_regex /^[0-9]+ // /sql-backup-[0-9a-f]+-[0-9a-f]+/sql-backup-P-T/ --exec grep INJECTED $trace SELECT * FROM t1; --echo # Orphan #sql-backup files left in the database directory (expected: none) --replace_regex /sql-backup-[0-9a-f]+-[0-9a-f]+/sql-backup-P-T/ --list_files $datadir #sql-backup* --perl opendir(D, "$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/test") or die $!; my @f = grep { /^#sql-backup/ } readdir(D); open(F, ">$ENV{MYSQLTEST_VARDIR}/tmp/mdev41707_orphans.inc") or die $!; print F "--let \$orphans= ".scalar(@f)."\n"; close F; EOF --source $MYSQLTEST_VARDIR/tmp/mdev41707_orphans.inc if ($orphans) { --echo FAIL: $orphans orphan #sql-backup file(s) left after the successful ALTER --inc $failures } --echo # Step 2: next copying ALTER on the SAME connection --replace_regex /sql-backup-[0-9a-f]+-[0-9a-f]+/sql-backup-P-T/ --error 0,ER_ERROR_ON_RENAME ALTER TABLE t2 ADD COLUMN c INT, ALGORITHM=COPY; --echo errno: $mysql_errno if ($mysql_errno) { --echo FAIL: later copying ALTER on the same connection failed with errno $mysql_errno --inc $failures } --echo # Step 3: the same kind of ALTER from ANOTHER connection (informational) --connect (con2,localhost,root,,test) --error 0,ER_ERROR_ON_RENAME ALTER TABLE t2 FORCE, ALGORITHM=COPY; --echo errno: $mysql_errno --disconnect con2 --connection default --echo # Step 4: after a restart the orphan must not be left behind --source include/restart_mysqld.inc --perl opendir(D, "$ENV{MYSQLTEST_VARDIR}/mysqld.1/data/test") or die $!; my @f = grep { /^#sql-backup/ } readdir(D); open(F, ">$ENV{MYSQLTEST_VARDIR}/tmp/mdev41707_orphans.inc") or die $!; print F "--let \$orphans= ".scalar(@f)."\n"; close F; EOF --source $MYSQLTEST_VARDIR/tmp/mdev41707_orphans.inc --echo # orphan #sql-backup files after restart: $orphans if ($orphans) { --echo FAIL: $orphans orphan #sql-backup file(s) remain after restart --inc $failures } --remove_file $trace DROP TABLE t1, t2; if ($failures) { --die MDEV-41707 reproduced: $failures check(s) failed } --echo # all checks passed