summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/innodb/t/instant_alter_crash.test
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/suite/innodb/t/instant_alter_crash.test')
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_crash.test258
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;