1# Crash-safe InnoDB ALTER operations 2 3--source include/not_valgrind.inc 4--source include/have_debug.inc 5--source include/not_crashrep.inc 6 7--disable_query_log 8call mtr.add_suppression(' Cannot find a free slot for an undo log'); 9call mtr.add_suppression(' row_merge_rename_index_to_add failed with error 47'); 10call mtr.add_suppression(' Flagged corruption of `c[23]`'); 11call mtr.add_suppression(' Index `c[23]` .*is corrupted'); 12--enable_query_log 13 14--echo # 15--echo # Bug#20015132 ALTER TABLE FAILS TO CHECK IF TABLE IS CORRUPTED 16--echo # 17 18CREATE TABLE t1(c1 INT PRIMARY KEY, c2 CHAR(1), c3 INT UNSIGNED) ENGINE=InnoDB; 19--disable_testcase BUG#0000 20SET DEBUG='+d,ib_create_table_fail_too_many_trx'; 21--error ER_TOO_MANY_CONCURRENT_TRXS 22ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); 23 24SET DEBUG='-d,ib_create_table_fail_too_many_trx'; 25--enable_testcase 26ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); 27# Flag the secondary indexes corrupted. 28SET DEBUG='+d,dict_set_index_corrupted'; 29CHECK TABLE t1; 30 31# Ensure that the corruption is permanent. 32--source include/restart_mysqld.inc 33CHECK TABLE t1; 34ALTER TABLE t1 DROP INDEX c2; 35CHECK TABLE t1; 36# We refuse an ALTER TABLE that would modify the InnoDB data dictionary 37# while leaving some of the table corrupted. 38--error ER_CHECK_NO_SUCH_TABLE 39ALTER TABLE t1 ADD INDEX (c2,c3); 40# This will rebuild the table, uncorrupting all secondary indexes. 41ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL; 42CHECK TABLE t1; 43ALTER TABLE t1 ADD INDEX (c2,c3); 44DROP TABLE t1; 45 46let $MYSQLD_DATADIR= `select @@datadir`; 47let datadir= `select @@datadir`; 48 49# These are from include/shutdown_mysqld.inc and allow to call start_mysqld.inc 50--let $_server_id= `SELECT @@server_id` 51--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect 52 53--echo # 54--echo # Bug #14669848 CRASH DURING ALTER MAKES ORIGINAL TABLE INACCESSIBLE 55--echo # 56--echo # -- Scenario 1: 57--echo # Crash the server in ha_innobase::commit_inplace_alter_table() 58--echo # just after committing the dictionary changes. 59 60CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; 61INSERT INTO t1 VALUES (1,2),(3,4); 62SET DEBUG='d,innodb_alter_commit_crash_after_commit'; 63 64let $orig_table_id = `SELECT table_id 65 FROM information_schema.innodb_tables 66 WHERE name = 'test/t1'`; 67 68# Write file to make mysql-test-run.pl expect crash 69--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect 70 71--error 2013 72ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); 73 74--echo # Restart mysqld after the crash and reconnect. 75--source include/start_mysqld.inc 76 77let $temp_table_name = `SELECT SUBSTR(name, 6) 78 FROM information_schema.innodb_tables 79 WHERE table_id = $orig_table_id`; 80 81--echo # Files in datadir after manual recovery. 82--list_files $MYSQLD_DATADIR/test 83 84SHOW TABLES; 85SHOW CREATE TABLE t1; 86INSERT INTO t1 VALUES (5,6),(7,8); 87SELECT * FROM t1; 88DROP TABLE t1; 89 90CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB; 91ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); 92DROP TABLE t1; 93 94--echo # -- Scenario 2: 95--echo # Crash the server in ha_innobase::commit_inplace_alter_table() 96--echo # just before committing the dictionary changes, but after 97--echo # writing the MLOG_FILE_RENAME records. As the mini-transaction 98--echo # is not committed, the renames will not be replayed. 99 100CREATE TABLE t2 (f1 int not null, f2 int not null) ENGINE=InnoDB; 101INSERT INTO t2 VALUES (1,2),(3,4); 102SET DEBUG='d,innodb_alter_commit_crash_before_commit'; 103 104let $orig_table_id = `SELECT table_id 105 FROM information_schema.innodb_tables 106 WHERE name = 'test/t2'`; 107 108# Write file to make mysql-test-run.pl expect crash 109--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect 110 111--error 2013 112ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); 113 114--echo # Startup the server after the crash 115--source include/start_mysqld.inc 116 117SHOW TABLES; 118INSERT INTO t2 VALUES (5,6),(7,8); 119SELECT * from t2; 120SHOW CREATE TABLE t2; 121DROP TABLE t2; 122 123CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB; 124ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); 125DROP TABLE t2; 126--list_files $MYSQLD_DATADIR/test 127 128--echo # ------------------------- 129--echo # End of Testing Scenario 2 130--echo # ------------------------- 131 132--echo # 133--echo # Bug#19330255 CRASH DURING ALTER TABLE LEADS TO 134--echo # DATA DICTIONARY INCONSISTENCY 135--echo # 136 137CREATE TABLE t1(a int PRIMARY KEY, b varchar(150), c int NOT NULL); 138INSERT INTO t1 SET a=1,c=2; 139SET DEBUG='d,innodb_alter_commit_crash_after_commit'; 140 141let $orig_table_id = `select table_id from 142 information_schema.innodb_tables where name = 'test/t1'`; 143 144# Write file to make mysql-test-run.pl expect crash 145--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect 146 147--error 2013 148ALTER TABLE t1 ADD INDEX (b), CHANGE c d int; 149 150--echo # Restart mysqld after the crash and reconnect. 151--source include/start_mysqld.inc 152 153--echo # Files in datadir after manual recovery. 154--list_files $MYSQLD_DATADIR/test 155 156SHOW TABLES; 157SHOW CREATE TABLE t1; 158SELECT * FROM t1; 159DROP TABLE t1; 160