diff options
Diffstat (limited to 'mysql-test/suite/innodb/t/table_flags.test')
-rw-r--r-- | mysql-test/suite/innodb/t/table_flags.test | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test new file mode 100644 index 00000000..34204ae1 --- /dev/null +++ b/mysql-test/suite/innodb/t/table_flags.test @@ -0,0 +1,253 @@ +--source include/innodb_page_size.inc +# Embedded server tests do not support restarting +--source include/not_embedded.inc +# Slow shutdown may take more than 120 seconds under Valgrind, +# causing the server to be (silently) killed. +# Due to that, crash recovery could "heal" the damage that our +# Perl code is inflicting, and the SELECT statements could succeed +# instead of failing with ER_NO_SUCH_TABLE_IN_ENGINE. +--source include/not_valgrind.inc + +--disable_query_log +call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found"); +call mtr.add_suppression("InnoDB: incorrect flags in SYS_TABLES"); +call mtr.add_suppression("InnoDB: Table test/t[cp] in InnoDB data dictionary contains invalid flags\\. SYS_TABLES\\.TYPE=(129|289|3873|1232[31]) SYS_TABLES\\.N_COLS=2147483649\\r?$"); +call mtr.add_suppression("InnoDB: Table test/tr in InnoDB data dictionary contains invalid flags\\. SYS_TABLES\\.TYPE=65 SYS_TABLES\\.MIX_LEN=4294967295\\r?$"); +call mtr.add_suppression("InnoDB: Refusing to load '\\..test.td\\.ibd' \\(id=3, flags=0x([2e]1)\\); dictionary contains id=3, flags=0x100\\1\\r?$"); +call mtr.add_suppression("InnoDB: Refusing to load '\\..test.td\\.ibd' \\(id=3, flags=0x(1[2ae]1)\\); dictionary contains id=3, flags=0x10\\1\\r?$"); +call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`.`td` because it could not be opened\\."); +# FIXME: Remove the following spam due to invalid flags for test.td +call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation"); +call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified"); +call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of file "); +call mtr.add_suppression("InnoDB: Parent table of FTS auxiliary table .* not found."); +FLUSH TABLES; +--enable_query_log + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +let bugdir= $MYSQLTEST_VARDIR/tmp/table_flags; +--mkdir $bugdir +--let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err + +--let $d=--innodb-data-home-dir=$bugdir --innodb-log-group-home-dir=$bugdir +--let $d=$d --innodb-data-file-path=ibdata1:1M:autoextend +--let $d=$d --innodb-undo-tablespaces=0 +--let $d=$d --skip-innodb-fast-shutdown +--let $restart_noprint=1 +--let $restart_parameters=$d --innodb-stats-persistent=0 +--source include/restart_mysqld.inc + +SET GLOBAL innodb_file_per_table=1; +CREATE TABLE tr(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +CREATE TABLE tc(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=COMPACT; +CREATE TABLE td(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +SET innodb_strict_mode=OFF; +CREATE TABLE tz(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=COMPRESSED +KEY_BLOCK_SIZE=1; +SET innodb_strict_mode=ON; +# PAGE_COMPRESSED is supported starting with MariaDB 10.1.0 +CREATE TABLE tp(a INT PRIMARY KEY)ENGINE=InnoDB ROW_FORMAT=DYNAMIC +PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9; + +--source include/shutdown_mysqld.inc +--perl +use strict; +do "$ENV{MTR_SUITE_DIR}/include/crc32.pl"; +my $ps= $ENV{INNODB_PAGE_SIZE}; +my $file= "$ENV{bugdir}/ibdata1"; +open(FILE, "+<", $file) || die "Unable to open $file\n"; +die "Unable to read $file" unless sysread(FILE, $_, 58) == 58; +my $full_crc32 = unpack("N",substr($_,54,4)) & 0x10; # FIL_SPACE_FLAGS +# Read DICT_HDR_TABLES, the root page number of CLUST_IND (SYS_TABLES.NAME). +sysseek(FILE, 7*$ps+38+32, 0) || die "Unable to seek $file"; +die "Unable to read $file" unless sysread(FILE, $_, 4) == 4; +my $sys_tables_root = unpack("N", $_); +my $page; +print "SYS_TABLES clustered index root page ($sys_tables_root):\n"; +sysseek(FILE, $sys_tables_root*$ps, 0) || die "Unable to seek $file"; +die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; +open(BACKUP, ">$ENV{bugdir}/sys_tables.bin") || die "Unable to open backup\n"; +syswrite(BACKUP, $page, $ps)==$ps || die "Unable to write backup\n"; +close(BACKUP) || die "Unable to close backup\n"; +print "N_RECS=", unpack("n", substr($page,38+16,2)); +print "; LEVEL=", unpack("n", substr($page,38+26,2)); +print "; INDEX_ID=0x", unpack("H*", substr($page,38+28,8)), "\n"; +my @fields=("NAME","DB_TRX_ID","DB_ROLL_PTR", + "ID","N_COLS","TYPE","MIX_ID","MIX_LEN","CLUSTER_NAME","SPACE"); +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; + 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)" + } elsif ($n_fields > 1 && $i == 0) { + $name= substr($page,$offset+$start,$end-$start); + print "'$name'" + } else { + print "0x", unpack("H*", substr($page,$offset+$start,$end-$start)) + } + # Corrupt SYS_TABLES.TYPE + if ($i == 5) + { + my $flags= 0; + if ($name eq 'test/tr') { + $flags= 0x40 # DATA_DIR (largely ignored by 10.1+) + } elsif ($name eq 'test/tc') { + $flags= 0x80 # 10.1 PAGE_COMPRESSED + } elsif ($name eq 'test/td') { + $flags= 0xf00 # PAGE_COMPRESSION_LEVEL=15 (0..9 is valid) + # As part of the MDEV-12873 fix, because the + # PAGE_COMPRESSED=YES flag was not set, we will assume that + # this table was actually created with 10.2.2..10.2.6 + # using PAGE_COMPRESSED=YES PAGE_COMPRESSION_LEVEL=7. + } elsif ($name eq 'test/tz') { + $flags= 0x3000 # 10.1 ATOMIC_WRITES=3 (0..2 is valid) + } elsif ($name eq 'test/tp') { + $flags= 0x880 # 10.1 PAGE_COMPRESSED, PAGE_COMPRESSION_LEVEL=8 + # (in 10.2.2 through 10.2.6, this is interpreted as + # PAGE_COMPRESSION_LEVEL=4 without PAGE_COMPRESSED + # but with SHARED_SPACE, which should be invalid) + } + + substr($page,$offset+$start,$end-$start)= pack( + "N", $flags ^ + unpack("N", substr($page,$offset+$start,$end-$start))) + if $flags; + } + # Corrupt SYS_TABLES.MIX_LEN (ignored for ROW_FORMAT=REDUNDANT) + if ($i == 7 && $name eq 'test/tr') + { + substr($page,$offset+$start,$end-$start)= chr(255) x 4; + } + $start= $end & 0x7f; + } + print ")\n"; +} +my $polynomial = 0x82f63b78; # CRC-32C +if ($full_crc32) +{ + my $ck = mycrc32(substr($page, 0, $ps-4), 0, $polynomial); + substr($page, $ps-4, 4) = pack("N", $ck); +} +else +{ + my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^ + mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial)); + substr($page,0,4)=$ck; + substr($page,$ps-8,4)=$ck; +} +sysseek(FILE, $sys_tables_root*$ps, 0) || die "Unable to seek $file"; +syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; +close(FILE) || die "Unable to close $file\n"; +EOF +--source include/start_mysqld.inc + +--error ER_NO_SUCH_TABLE_IN_ENGINE +SHOW CREATE TABLE tr; +--error ER_NO_SUCH_TABLE_IN_ENGINE +SHOW CREATE TABLE tc; +--error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT * FROM tc; +SHOW CREATE TABLE td; +SELECT * FROM td; +# This table was converted to NO_ROLLBACK due to the SYS_TABLES.TYPE change. +SHOW CREATE TABLE tz; +BEGIN; +INSERT INTO tz VALUES(42); +ROLLBACK; +SELECT * FROM tz; +--error ER_NO_SUCH_TABLE_IN_ENGINE +SHOW CREATE TABLE tp; + +--source include/shutdown_mysqld.inc + +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; +--let SEARCH_PATTERN= InnoDB: Table test/t[cp] in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649 +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Table test/tr in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b +--source include/search_pattern_in_file.inc + +# Restore the backup of the corrupted SYS_TABLES clustered index root page +--perl +use strict; +my $ps= $ENV{INNODB_PAGE_SIZE}; +my $file= "$ENV{bugdir}/ibdata1"; +open(FILE, "+<", $file) || die "Unable to open $file\n"; +open(BACKUP, "<$ENV{bugdir}/sys_tables.bin") || die "Unable to open backup\n"; +# Read DICT_HDR_TABLES, the root page number of CLUST_IND (SYS_TABLES.NAME). +sysseek(FILE, 7*$ps+38+32, 0) || die "Unable to seek $file"; +die "Unable to read $file\n" unless sysread(FILE, $_, 4) == 4; +my $sys_tables_root = unpack("N", $_); +print "Restoring SYS_TABLES clustered index root page ($sys_tables_root)\n"; +sysseek(FILE, $sys_tables_root*$ps, 0) || die "Unable to seek $file"; +die "Unable to read backup\n" unless sysread(BACKUP, $_, $ps) == $ps; +die "Unable to restore backup\n" unless syswrite(FILE, $_, $ps) == $ps; +close(BACKUP); +close(FILE) || die "Unable to close $file\n"; +EOF +--source include/start_mysqld.inc + +SHOW CREATE TABLE tr; +SHOW CREATE TABLE tc; +SHOW CREATE TABLE td; +SHOW CREATE TABLE tz; +SHOW CREATE TABLE tp; + +BEGIN; +INSERT INTO tr VALUES(1); +INSERT INTO tc VALUES(1); +INSERT INTO td VALUES(1); +# We cannot access tz, because due to our fiddling of the NO_ROLLBACK flag, +# it now has a record with DB_TRX_ID=0, which is invalid for +# transactional tables until MDEV-12288 is implemented. +# INSERT INTO tz VALUES(1); +INSERT INTO tp VALUES(1); +ROLLBACK; + +SELECT * FROM tr; +SELECT * FROM tc; +SELECT * FROM td; +# SELECT * FROM tz; +SELECT * FROM tp; + +DROP TABLE tr,tc,td,tz,tp; + +--let $restart_parameters= +--source include/restart_mysqld.inc + +--error 0,1 +--remove_file $bugdir/ibtmp1 +--error 0,1 +--remove_file $bugdir/ib_buffer_pool + +--list_files $bugdir +--remove_files_wildcard $bugdir +--rmdir $bugdir + +call mtr.add_suppression("ERROR HY000: Can't create table `test`.`t1`"); +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1(f1 INT, f2 VARCHAR(1), KEY k1(f2), + FULLTEXT KEY(f2), + FOREIGN KEY (f2) REFERENCES t1(f3))ENGINE=InnoDB; + +--echo # +--echo # MDEV-23199 page_compression flag is missing +--echo # for full_crc32 tablespace +--echo # + +CREATE TABLE t1(f1 BIGINT PRIMARY KEY)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); +ALTER TABLE t1 PAGE_COMPRESSED = 1; +INSERT INTO t1 VALUES(2); +let $shutdown_timeout = 0; +--source include/restart_mysqld.inc +DROP TABLE t1; |