mirror of
https://github.com/MariaDB/server.git
synced 2025-09-11 05:52:26 +03:00
Probably due to the changes to page flushing in MDEV-23399
(commit 7cffb5f6e8
) the command
CHECK TABLE would occasionally report a different number of rows
for the corrupted secondary index. (The reported number was 991
instead of 990 on one occasion.)
Let us map all numbers to 990 in the output. We only care that the
injected corruption will be detected.
114 lines
4.0 KiB
Plaintext
114 lines
4.0 KiB
Plaintext
--source include/have_innodb.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");
|
|
--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;
|
|
|
|
# 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=
|
|
--source include/start_mysqld.inc
|
|
SET GLOBAL innodb_fast_shutdown=0;
|
|
--source include/restart_mysqld.inc
|
|
|
|
# Cleanup
|
|
DROP TABLE t1;
|