diff options
Diffstat (limited to 'mysql-test/suite/innodb/t/instant_alter_crash.test')
-rw-r--r-- | mysql-test/suite/innodb/t/instant_alter_crash.test | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/mysql-test/suite/innodb/t/instant_alter_crash.test b/mysql-test/suite/innodb/t/instant_alter_crash.test new file mode 100644 index 00000000..b687664d --- /dev/null +++ b/mysql-test/suite/innodb/t/instant_alter_crash.test @@ -0,0 +1,258 @@ +--source include/have_innodb.inc +# The embedded server tests do not support restarting. +--source include/not_embedded.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +FLUSH TABLES; + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +--echo # +--echo # MDEV-11369: Instant ADD COLUMN for InnoDB +--echo # + +CREATE TABLE t1(id INT PRIMARY KEY, c2 INT UNIQUE) +ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +CREATE TABLE t2 LIKE t1; +INSERT INTO t1 VALUES(0,2); +INSERT INTO t2 VALUES(2,1); +ALTER TABLE t2 ADD COLUMN (c3 TEXT NOT NULL DEFAULT 'De finibus bonorum'); +BEGIN; +INSERT INTO t2 VALUES(3,4,'accusantium doloremque laudantium'); + +connect ddl, localhost, root; +SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever'; +--send +ALTER TABLE t1 ADD COLUMN (c3 TEXT NOT NULL DEFAULT ' et malorum'); + +connection default; +SET DEBUG_SYNC='now WAIT_FOR ddl'; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +COMMIT; + +--source include/kill_mysqld.inc +disconnect ddl; +--source include/start_mysqld.inc + +SELECT * FROM t1; +SELECT * FROM t2; +BEGIN; +DELETE FROM t1; +ROLLBACK; +--source include/wait_all_purged.inc + +INSERT INTO t2 VALUES +(16,1551,'Omnium enim rerum'),(128,1571,' principia parva sunt'); + +BEGIN; +UPDATE t1 SET c2=c2+1; + +connect ddl, localhost, root; +SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever'; +--send +ALTER TABLE t2 DROP COLUMN c3, ADD COLUMN c5 TEXT DEFAULT 'naturam abhorrere'; + +connection default; +SET DEBUG_SYNC='now WAIT_FOR ddl'; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +COMMIT; + +--source include/kill_mysqld.inc +disconnect ddl; +--source include/start_mysqld.inc + +SELECT * FROM t1; +SELECT * FROM t2; +BEGIN; +INSERT INTO t1 SET id=1; +DELETE FROM t2; +ROLLBACK; +--source include/wait_all_purged.inc + +INSERT INTO t2 VALUES (64,42,'De finibus bonorum'), (347,33101,' et malorum'); +BEGIN; +DELETE FROM t1; + +connect ddl, localhost, root; +ALTER TABLE t2 DROP COLUMN c3; +SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever'; +--send +ALTER TABLE t2 ADD COLUMN (c4 TEXT NOT NULL DEFAULT ' et malorum'); + +connection default; +SET DEBUG_SYNC='now WAIT_FOR ddl'; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +COMMIT; + +--source include/kill_mysqld.inc +disconnect ddl; +--source include/start_mysqld.inc + +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN= \[Note\] InnoDB: Rolled back recovered transaction ; +-- source include/search_pattern_in_file.inc + +SELECT * FROM t1; +SELECT * FROM t2; +BEGIN; +INSERT INTO t1 SET id=1; +DELETE FROM t2; +ROLLBACK; +--source include/wait_all_purged.inc + +FLUSH TABLE t1,t2 FOR EXPORT; + +# At this point, t1 is empty and t2 contains a 'default row'. + +# The following is based on innodb.table_flags and innodb.dml_purge: +--perl +use strict; +my $ps= $ENV{INNODB_PAGE_SIZE}; +foreach my $table ('t1','t2') { +my $file= "$ENV{MYSQLD_DATADIR}/test/$table.ibd"; +open(FILE, "<", $file) || die "Unable to open $file\n"; +my $page; +sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file"; +die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; +print "$table clustered index root page"; +print "(type ", unpack("n", substr($page,24,2)), "):\n"; +print "N_RECS=", unpack("n", substr($page,38+16,2)); +print "; LEVEL=", unpack("n", substr($page,38+26,2)), "\n"; +my @fields=("id","DB_TRX_ID","DB_ROLL_PTR", "c2","c3","c4"); +for (my $offset= 0x65; $offset; + $offset= unpack("n", substr($page,$offset-2,2))) +{ + print "header=0x", unpack("H*",substr($page,$offset-6,6)), " ("; + my $n_fields= unpack("n", substr($page,$offset-4,2)) >> 1 & 0x3ff; + my $start= 0; + my $name; + if (unpack("C", substr($page,$offset-3,1)) & 1) { + for (my $i= 0; $i < $n_fields; $i++) { + my $end= unpack("C", substr($page, $offset-7-$i, 1)); + print ",\n " if $i; + print "$fields[$i]="; + if ($end & 0x80) { + print "NULL(", ($end & 0x7f) - $start, " bytes)" + } else { + print "0x", unpack("H*", substr($page,$offset+$start,$end-$start)) + } + $start= $end & 0x7f; + } + } else { + for (my $i= 0; $i < $n_fields; $i++) { + my $end= unpack("n", substr($page, $offset-8-2*$i, 2)); + print ",\n " if $i; + if ($i > 2 && !(~unpack("C",substr($page,$offset-6,1)) & 0x30)) { + if ($i == 3) { + print "BLOB="; + $start += 8; # skip the space_id,page_number + } else { + print "$fields[$i - 1]="; + } + } else { + print "$fields[$i]="; + } + if ($end & 0x8000) { + print "NULL(", ($end & 0x7fff) - $start, " bytes)" + } else { + print "0x", unpack("H*", substr($page,$offset+$start,($end-$start) & 0x3fff)) + } + $start= $end & 0x3fff; + } + } + print ")\n"; +} +close(FILE) || die "Unable to close $file\n"; +} +EOF + +UNLOCK TABLES; + +DELETE FROM t2; +--source include/wait_all_purged.inc + +--echo # +--echo # MDEV-24323 Crash on recovery after kill during instant ADD COLUMN +--echo # +BEGIN; +INSERT INTO t1 VALUES(0,0); + +connect ddl, localhost, root; +CREATE TABLE t3(id INT PRIMARY KEY, c2 INT, v2 INT AS(c2) VIRTUAL, UNIQUE(v2)) +ENGINE=InnoDB; +INSERT INTO t3 SET id=1,c2=1; + +SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever'; +--send +ALTER TABLE t3 ADD COLUMN c3 TEXT NOT NULL DEFAULT 'sic transit gloria mundi'; + +connection default; +SET DEBUG_SYNC='now WAIT_FOR ddl'; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +COMMIT; + +--source include/kill_mysqld.inc +disconnect ddl; +--source include/start_mysqld.inc + +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +DROP TABLE t2,t3; + +--echo # +--echo # MDEV-29440 InnoDB instant ALTER TABLE recovery wrongly uses +--echo # READ COMMITTED isolation level instead of READ UNCOMMITTED +--echo # +CREATE TABLE t2(a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1),(2),(3),(4),(5),(6); + +BEGIN; +DELETE FROM t1; + +connect ddl, localhost, root; +SET DEBUG_SYNC='innodb_alter_inplace_before_commit SIGNAL ddl WAIT_FOR ever'; +--send +ALTER TABLE t2 ADD COLUMN b TINYINT UNSIGNED NOT NULL DEFAULT 42 FIRST; + +connection default; +SET DEBUG_SYNC='now WAIT_FOR ddl'; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +COMMIT; + +--source include/kill_mysqld.inc +disconnect ddl; +--source include/start_mysqld.inc + +CHECK TABLE t2; +DROP TABLE t1,t2; + +--list_files $MYSQLD_DATADIR/test + +--echo # +--echo # MDEV-26198 Assertion `0' failed in row_log_table_apply_op during +--echo # ADD PRIMARY KEY or OPTIMIZE TABLE +--echo # +CREATE TABLE t1(f1 year default null, f2 year default null, + f3 text, f4 year default null, f5 year default null, + f6 year default null, f7 year default null, + f8 year default null)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +INSERT INTO t1 VALUES(1, 1, 1, 1, 1, 1, 1, 1); +ALTER TABLE t1 ADD COLUMN f9 year default null, ALGORITHM=INPLACE; +set DEBUG_SYNC="row_log_table_apply1_before SIGNAL con1_insert WAIT_FOR con1_finish"; +send ALTER TABLE t1 ROW_FORMAT=REDUNDANT, ADD COLUMN f10 YEAR DEFAULT NULL, ALGORITHM=INPLACE; + +connect(con1,localhost,root,,,); +SET DEBUG_SYNC="now WAIT_FOR con1_insert"; +INSERT IGNORE INTO t1 (f3) VALUES ( 'b' ); +INSERT IGNORE INTO t1 (f3) VALUES ( 'l' ); +SET DEBUG_SYNC="now SIGNAL con1_finish"; + +connection default; +reap; +disconnect con1; +SET DEBUG_SYNC=RESET; +CHECK TABLE t1; +DROP TABLE t1; |