diff --git a/mysql-test/suite/innodb/r/alter_kill.result b/mysql-test/suite/innodb/r/alter_kill.result new file mode 100644 index 00000000000..bdba057acef --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_kill.result @@ -0,0 +1,76 @@ +# +# Bug#16720368 INNODB CRASHES ON BROKEN #SQL*.IBD FILE AT STARTUP +# +SET GLOBAL innodb_file_per_table=1; +CREATE TABLE bug16720368_1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE bug16720368 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO bug16720368 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8); +# Cleanly shutdown mysqld +# Corrupt FIL_PAGE_OFFSET in bug16720368.ibd, +# and update the checksum to the "don't care" value. +# Restart mysqld +# This will succeed after a clean shutdown, due to +# fil_open_single_table_tablespace(check_space_id=FALSE). +SELECT COUNT(*) FROM bug16720368; +COUNT(*) +8 +INSERT INTO bug16720368_1 VALUES(1); +# Kill the server to do an unclean shutdown. +# The corruption should not prevent startup after crash recovery, +# because there is no redo log for the corrupted tablespace. +# The table is unaccessible, because after a crash we will +# validate the tablespace header. +SELECT COUNT(*) FROM bug16720368; +ERROR 42S02: Table 'test.bug16720368' doesn't exist +INSERT INTO bug16720368 VALUES(0,1); +ERROR 42S02: Table 'test.bug16720368' doesn't exist +# Kill the server to do an unclean shutdown. +# The table is readable thanks to innodb-force-recovery. +SELECT COUNT(*) FROM bug16720368; +COUNT(*) +8 +INSERT INTO bug16720368 VALUES(0,1); +ERROR HY000: Operation not allowed when innodb_forced_recovery > 0. +# Shut down the server cleanly to hide the corruption. +# The table is accessible, because after a clean shutdown we will +# NOT validate the tablespace header. +# We can modify the existing pages, but we cannot allocate or free +# any pages, because that would hit the corruption on page 0. +SELECT COUNT(*) FROM bug16720368; +COUNT(*) +8 +INSERT INTO bug16720368 VALUES(0,1); +# Shut down the server to uncorrupt the data. +# Restart the server after uncorrupting the file. +INSERT INTO bug16720368 VALUES(9,1); +SELECT COUNT(*) FROM bug16720368; +COUNT(*) +10 +DROP TABLE bug16720368, bug16720368_1; +# +# Bug#16735660 ASSERT TABLE2 == NULL, ROLLBACK OF RESURRECTED TXNS, +# DICT_TABLE_ADD_TO_CACHE +# +SET GLOBAL innodb_file_per_table=1; +CREATE TEMPORARY TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 VALUES(42); +CREATE TABLE bug16735660 (a INT PRIMARY KEY) ENGINE=InnoDB; +XA START 'x'; +INSERT INTO bug16735660 VALUES(1),(2),(3); +XA END 'x'; +XA PREPARE 'x'; +# Attempt to start without an *.ibd file. +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +SELECT * FROM bug16735660; +a +1 +2 +3 +XA RECOVER; +formatID gtrid_length bqual_length data +1 1 0 x +XA ROLLBACK 'x'; +SELECT * FROM bug16735660; +a +DROP TABLE bug16735660; diff --git a/mysql-test/suite/innodb/t/alter_kill-master.opt b/mysql-test/suite/innodb/t/alter_kill-master.opt new file mode 100644 index 00000000000..e472160c2b7 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_kill-master.opt @@ -0,0 +1 @@ +--innodb-doublewrite=false diff --git a/mysql-test/suite/innodb/t/alter_kill.test b/mysql-test/suite/innodb/t/alter_kill.test new file mode 100644 index 00000000000..e85498825d6 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_kill.test @@ -0,0 +1,174 @@ +# The embedded server does not support restarting in mysql-test-run. +-- source include/not_embedded.inc + +let MYSQLD_DATADIR=`select @@datadir`; +let PAGE_SIZE=`select @@innodb_page_size`; + +-- disable_query_log +call mtr.add_suppression("InnoDB: innodb_force_recovery is on."); +call mtr.add_suppression("InnoDB: Tablespace open failed for.*bug16720368"); +call mtr.add_suppression("InnoDB: Failed to find tablespace.*bug16720368"); +call mtr.add_suppression("InnoDB:.*inconsistent data.*test/bug16720368"); +call mtr.add_suppression("InnoDB: Could not find.*test/bug16720368"); +call mtr.add_suppression("Found 1 prepared XA transactions"); +call mtr.add_suppression("InnoDB: .*test.*bug16720368.*missing"); +call mtr.add_suppression("InnoDB: Operating system error.*in a file operation"); +call mtr.add_suppression("InnoDB: \(The error means\|If you are\)"); +-- enable_query_log + +-- echo # +-- echo # Bug#16720368 INNODB CRASHES ON BROKEN #SQL*.IBD FILE AT STARTUP +-- echo # + +SET GLOBAL innodb_file_per_table=1; + +CREATE TABLE bug16720368_1 (a INT PRIMARY KEY) ENGINE=InnoDB; + +connect (con1,localhost,root); +CREATE TABLE bug16720368 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO bug16720368 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8); + +connection default; + +-- echo # Cleanly shutdown mysqld +-- source include/shutdown_mysqld.inc + +disconnect con1; + +-- echo # Corrupt FIL_PAGE_OFFSET in bug16720368.ibd, +-- echo # and update the checksum to the "don't care" value. +perl; +my $file = "$ENV{MYSQLD_DATADIR}/test/bug16720368.ibd"; +open(FILE, "+<$file") || die "Unable to open $file"; +print FILE pack("H*","deadbeefc001cafe") || die "Unable to write $file"; +seek(FILE, $ENV{PAGE_SIZE}-8, 0) || die "Unable to seek $file"; +print FILE pack("H*","deadbeef") || die "Unable to write $file"; +close(FILE) || die "Unable to close $file"; +EOF + +-- echo # Restart mysqld +-- source include/start_mysqld.inc + +-- echo # This will succeed after a clean shutdown, due to +-- echo # fil_open_single_table_tablespace(check_space_id=FALSE). +SELECT COUNT(*) FROM bug16720368; + +INSERT INTO bug16720368_1 VALUES(1); + +-- echo # Kill the server to do an unclean shutdown. +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 0 +-- source include/wait_until_disconnected.inc + +-- echo # The corruption should not prevent startup after crash recovery, +-- echo # because there is no redo log for the corrupted tablespace. +-- source include/start_mysqld.inc + +-- echo # The table is unaccessible, because after a crash we will +-- echo # validate the tablespace header. +--error ER_NO_SUCH_TABLE +SELECT COUNT(*) FROM bug16720368; +--error ER_NO_SUCH_TABLE +INSERT INTO bug16720368 VALUES(0,1); + +-- echo # Kill the server to do an unclean shutdown. +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 0 +-- source include/wait_until_disconnected.inc + +-- exec echo "restart: --innodb-force-recovery=3" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc +-- disable_reconnect + +-- echo # The table is readable thanks to innodb-force-recovery. +SELECT COUNT(*) FROM bug16720368; +--error ER_INNODB_FORCED_RECOVERY +INSERT INTO bug16720368 VALUES(0,1); + +-- echo # Shut down the server cleanly to hide the corruption. +-- source include/restart_mysqld.inc + +-- echo # The table is accessible, because after a clean shutdown we will +-- echo # NOT validate the tablespace header. +-- echo # We can modify the existing pages, but we cannot allocate or free +-- echo # any pages, because that would hit the corruption on page 0. +SELECT COUNT(*) FROM bug16720368; +INSERT INTO bug16720368 VALUES(0,1); + +-- echo # Shut down the server to uncorrupt the data. +-- source include/shutdown_mysqld.inc + +# Uncorrupt the FIL_PAGE_OFFSET. +perl; +my $file = "$ENV{MYSQLD_DATADIR}/test/bug16720368.ibd"; +open(FILE, "+<$file") || die "Unable to open $file"; +# Uncorrupt FIL_PAGE_OFFSET. +print FILE pack("H*","deadbeef00000000") || die "Unable to write $file"; +close(FILE) || die "Unable to close $file"; +EOF + +-- echo # Restart the server after uncorrupting the file. +-- source include/start_mysqld.inc + +INSERT INTO bug16720368 VALUES(9,1); +SELECT COUNT(*) FROM bug16720368; +# A debug assertion would fail in buf_block_align_instance() +# if we did not uncorrupt the page number first. +DROP TABLE bug16720368, bug16720368_1; + +-- echo # +-- echo # Bug#16735660 ASSERT TABLE2 == NULL, ROLLBACK OF RESURRECTED TXNS, +-- echo # DICT_TABLE_ADD_TO_CACHE +-- echo # + +SET GLOBAL innodb_file_per_table=1; + +CREATE TEMPORARY TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +BEGIN; +INSERT INTO t1 VALUES(42); + +-- connect (con1,localhost,root) + +CREATE TABLE bug16735660 (a INT PRIMARY KEY) ENGINE=InnoDB; + +XA START 'x'; +INSERT INTO bug16735660 VALUES(1),(2),(3); +XA END 'x'; +XA PREPARE 'x'; + +-- connect (con2,localhost,root) + +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 0 +-- source include/wait_until_disconnected.inc +-- disconnect con1 +-- disconnect con2 + +-- connection default + +-- move_file $MYSQLD_DATADIR/test/bug16735660.ibd $MYSQLD_DATADIR/bug16735660.omg + +-- echo # Attempt to start without an *.ibd file. +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/my_restart.err; +-- error 1 +-- exec $MYSQLD_CMD --console > $SEARCH_FILE 2>&1; + +let SEARCH_PATTERN= \[ERROR\] InnoDB: Tablespace [0-9]+ was not found at \..test.bug16735660\.ibd\.; +-- source include/search_pattern_in_file.inc + +-- move_file $MYSQLD_DATADIR/bug16735660.omg $MYSQLD_DATADIR/test/bug16735660.ibd + +-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc +-- disable_reconnect + +SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +SELECT * FROM bug16735660; + +XA RECOVER; +XA ROLLBACK 'x'; + +SELECT * FROM bug16735660; +DROP TABLE bug16735660;