From 320240be1d3bb5339156c76708003ca74fd6ee74 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Thu, 30 Apr 2015 10:23:36 -0400 Subject: [PATCH] Merge test for bug#72594 from upstream --- mysql-test/include/shutdown_mysqld.inc | 18 +++++ mysql-test/include/start_mysqld.inc | 14 ++++ .../innodb/r/innodb-alter-tempfile.result | 40 ++++++++++ .../suite/innodb/t/innodb-alter-tempfile.test | 75 +++++++++++++++++++ 4 files changed, 147 insertions(+) create mode 100644 mysql-test/include/shutdown_mysqld.inc create mode 100644 mysql-test/include/start_mysqld.inc create mode 100644 mysql-test/suite/innodb/r/innodb-alter-tempfile.result create mode 100644 mysql-test/suite/innodb/t/innodb-alter-tempfile.test diff --git a/mysql-test/include/shutdown_mysqld.inc b/mysql-test/include/shutdown_mysqld.inc new file mode 100644 index 00000000000..54bba1318e7 --- /dev/null +++ b/mysql-test/include/shutdown_mysqld.inc @@ -0,0 +1,18 @@ +# This is the first half of include/restart_mysqld.inc. +if ($rpl_inited) +{ + if (!$allow_rpl_inited) + { + --die ERROR IN TEST: When using the replication test framework (master-slave.inc, rpl_init.inc etc), use rpl_restart_server.inc instead of restart_mysqld.inc. If you know what you are doing and you really have to use restart_mysqld.inc, set allow_rpl_inited=1 before you source restart_mysqld.inc + } +} + +# Write file to make mysql-test-run.pl expect the "crash", but don't start it +--let $_server_id= `SELECT @@server_id` +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect +--exec echo "wait" > $_expect_file_name + +# Send shutdown to the connected server +--shutdown_server +--source include/wait_until_disconnected.inc + diff --git a/mysql-test/include/start_mysqld.inc b/mysql-test/include/start_mysqld.inc new file mode 100644 index 00000000000..983c566821e --- /dev/null +++ b/mysql-test/include/start_mysqld.inc @@ -0,0 +1,14 @@ +# Include this script only after using shutdown_mysqld.inc +# where $_expect_file_name was initialized. +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $_expect_file_name + +# Turn on reconnect +--enable_reconnect + +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc + +# Turn off reconnect again +--disable_reconnect + diff --git a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result new file mode 100644 index 00000000000..ce13ad0978b --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result @@ -0,0 +1,40 @@ +# +# Bug #18734396 INNODB IN-PLACE ALTER FAILURES BLOCK FUTURE ALTERS +# +# Temporary tablename will be unique. This makes sure that future +# in-place ALTERs of the same table will not be blocked due to +# temporary tablename. +# Crash the server in ha_innobase::commit_inplace_alter_table() +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; +SET debug='d,innodb_alter_commit_crash_before_commit'; +Warnings: +Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +# Write file to make mysql-test-run.pl expect crash +# Execute the statement that causes the crash +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); +ERROR HY000: Lost connection to MySQL server during query +# Startup the server after the crash +# Read and remember the temporary table name +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +# Consecutive Alter table does not create same temporary file name +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); +# Shutdown the server to allow manual recovery +# Manual recovery begin. The dictionary was not updated +# and the files were not renamed. The rebuilt table +# was left behind on purpose, to faciliate data recovery. +# Manual recovery end +# Startup the server after manual recovery +# Drop the orphaned rebuilt table. +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL, + PRIMARY KEY (`f2`,`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test new file mode 100644 index 00000000000..ec1ea35f1cf --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test @@ -0,0 +1,75 @@ +# Not supported in embedded +--source include/not_embedded.inc + +# This test case needs to crash the server. Needs a debug server. +--source include/have_debug.inc + +# Don't test this under valgrind, memory leaks will occur. +--source include/not_valgrind.inc + +# Avoid CrashReporter popup on Mac +--source include/not_crashrep.inc + +# InnoDB is required +--source include/have_innodb.inc + +--echo # +--echo # Bug #18734396 INNODB IN-PLACE ALTER FAILURES BLOCK FUTURE ALTERS +--echo # +--echo # Temporary tablename will be unique. This makes sure that future +--echo # in-place ALTERs of the same table will not be blocked due to +--echo # temporary tablename. + +let datadir= `select @@datadir`; + +--let $_server_id= `SELECT @@server_id` +--let $_expect_file_name=$MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect + +--echo # Crash the server in ha_innobase::commit_inplace_alter_table() +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; +SET debug='d,innodb_alter_commit_crash_before_commit'; + +let $orig_table_id = `SELECT table_id + FROM information_schema.innodb_sys_tables + WHERE name = 'test/t1'`; + +--echo # Write file to make mysql-test-run.pl expect crash +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--echo # Execute the statement that causes the crash +--error 2013 +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); +--echo # Startup the server after the crash +--source include/start_mysqld.inc + +--echo # Read and remember the temporary table name +let $temp_table_name = `SELECT SUBSTRING(name,6) + FROM information_schema.innodb_sys_tables + WHERE name LIKE "test/#sql-ib$orig_table_id%"`; +# This second copy is an environment variable for the perl script below. +let temp_table_name = $temp_table_name; +show create table t1; +--echo # Consecutive Alter table does not create same temporary file name +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); +--echo # Shutdown the server to allow manual recovery +--source include/shutdown_mysqld.inc + +--echo # Manual recovery begin. The dictionary was not updated +--echo # and the files were not renamed. The rebuilt table +--echo # was left behind on purpose, to faciliate data recovery. + +perl; +my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm"; +my $target_frm = "$ENV{'datadir'}/test/$ENV{'temp_table_name'}.frm"; +rename($frm_file[0], $target_frm); +EOF +--echo # Manual recovery end +--echo # Startup the server after manual recovery +--source include/start_mysqld.inc + +--echo # Drop the orphaned rebuilt table. +--disable_query_log +eval DROP TABLE `#mysql50#$temp_table_name`; +--enable_query_log +show create table t1; +drop table t1;