--source include/have_innodb.inc --source include/no_valgrind_without_big.inc # innodb_change_buffering_debug option is debug only --source include/have_debug.inc # Embedded server tests do not support restarting --source include/not_embedded.inc --source include/have_sequence.inc --disable_query_log call mtr.add_suppression("InnoDB: Failed to find tablespace for table `test`\\.`t1` in the cache\\. Attempting to load the tablespace with space id"); call mtr.add_suppression("InnoDB: Allocated tablespace ID \\d+ for test.t1, old maximum was"); call mtr.add_suppression("InnoDB: Failed to find tablespace for table `mysql`\\.`transaction_registry` in the cache\\. Attempting to load the tablespace with space id"); call mtr.add_suppression("InnoDB: Allocated tablespace ID \\d+ for mysql.transaction_registry, old maximum was"); call mtr.add_suppression("InnoDB: Trying to read 4096 bytes"); call mtr.add_suppression("InnoDB: File './test/t1.ibd' is corrupted"); --enable_query_log CREATE TABLE t1( a INT AUTO_INCREMENT PRIMARY KEY, b CHAR(1), c INT, INDEX(b)) ENGINE=InnoDB STATS_PERSISTENT=0; # The flag innodb_change_buffering_debug is only available in debug builds. # It instructs InnoDB to try to evict pages from the buffer pool when # change buffering is possible, so that the change buffer will be used # whenever possible. SET GLOBAL innodb_change_buffering_debug = 1; SET GLOBAL innodb_change_buffering=all; # Create enough rows for the table, so that the change buffer will be # used for modifying the secondary index page. There must be multiple # index pages, because changes to the root page are never buffered. INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_1024; let MYSQLD_DATADIR=`select @@datadir`; let PAGE_SIZE=`select @@innodb_page_size`; --source include/shutdown_mysqld.inc # Corrupt the change buffer bitmap, to claim that pages are clean perl; do "$ENV{MTR_SUITE_DIR}/include/crc32.pl"; my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd"; open(FILE, "+<$file") || die "Unable to open $file"; binmode FILE; my $ps= $ENV{PAGE_SIZE}; my $page; die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; # Clean the change buffer bitmap. substr($page,38,$ps - 38 - 8) = chr(0) x ($ps - 38 - 8); 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, $ps, 0) || die "Unable to rewind $file\n"; syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; close(FILE) || die "Unable to close $file"; EOF --let $restart_parameters= --innodb-force-recovery=6 --innodb-change-buffer-dump --source include/start_mysqld.inc --replace_regex /contains \d+ entries/contains 990 entries/ check table t1; --source include/shutdown_mysqld.inc # Truncate the file to 5 pages, as if it were empty perl; do "$ENV{MTR_SUITE_DIR}/include/crc32.pl"; my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd"; open(FILE, "+<$file") || die "Unable to open $file"; binmode FILE; my $ps= $ENV{PAGE_SIZE}; my $pages=5; my $page; die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS substr($page,46,4)=pack("N", $pages); 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, 0, 0) || die "Unable to rewind $file\n"; syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; truncate(FILE, $ps * $pages); close(FILE) || die "Unable to close $file"; EOF --let $restart_parameters=--innodb-force_recovery=0 --source include/start_mysqld.inc SET GLOBAL innodb_fast_shutdown=0; --source include/restart_mysqld.inc # Cleanup DROP TABLE t1;