mariadb/mysql-test/suite/innodb/t/doublewrite.test
Thirunarayanan Balathandayuthapani 4f7faa4bc8 MDEV-36650 Unexpected checkpoint in the test innodb.doublewrite
innodb.doublewrite: Skip the test case if we get an unexpected
checkpoint. This could happen because page cleaner thread
could be active after reading the initial checkpoint information.
2025-06-18 18:36:45 +05:30

212 lines
8.1 KiB
Text

--echo #
--echo # MDEV-32242 innodb.doublewrite test case always is skipped
--echo #
--source include/innodb_page_size.inc
--source include/not_embedded.inc
--disable_query_log
call mtr.add_suppression("InnoDB: Data file .* uses page size .* but the innodb_page_size start-up parameter is");
call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS");
call mtr.add_suppression("InnoDB: New log files created");
call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\.");
call mtr.add_suppression("InnoDB: Database creation was aborted");
call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)");
call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile");
call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: ");
call mtr.add_suppression("InnoDB: Inconsistent tablespace ID in .*t1\\.ibd");
call mtr.add_suppression("\\[Warning\\] Found 1 prepared XA transactions");
call mtr.add_suppression("InnoDB: Header page consists of zero bytes in datafile:");
call mtr.add_suppression("InnoDB: Page \\[page id: space=[1-9][0-9]*, page number=3\\] log sequence number 18446744073709551615 is in the future!");
call mtr.add_suppression("InnoDB: Your database may be corrupt or you may have copied the InnoDB tablespace but not the ib_logfile0");
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
--enable_query_log
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`;
let ALGO=`select @@innodb_checksum_algorithm`;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
create table t1 (f1 int primary key, f2 blob) stats_persistent=0, engine=innodb;
start transaction;
insert into t1 values(1, repeat('#',12));
insert into t1 values(2, repeat('+',12));
insert into t1 values(3, repeat('/',12));
insert into t1 values(4, repeat('-',12));
insert into t1 values(5, repeat('.',12));
commit work;
# Slow shutdown and restart to make sure ibuf merge is finished
SET GLOBAL innodb_fast_shutdown = 0;
let $shutdown_timeout=;
--source include/restart_mysqld.inc
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0,innodb_max_dirty_pages_pct=0;
let $wait_condition =
SELECT variable_value = 0
FROM information_schema.global_status
WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY';
--source include/wait_condition.inc
SET GLOBAL innodb_max_dirty_pages_pct=99;
--source ../include/no_checkpoint_start.inc
connect (dml,localhost,root,,);
XA START 'x';
insert into t1 values(6, repeat('%', @@innodb_page_size/2));
XA END 'x';
XA PREPARE 'x';
disconnect dml;
connection default;
flush table t1 for export;
# If we are skipping the test at this point due to an unexpected
# checkpoint then page cleaner could be active after reading the
# initial checkpoint information
--let CLEANUP_IF_CHECKPOINT=XA COMMIT 'x'; drop table t1;
--source ../include/no_checkpoint_end.inc
--copy_file $MYSQLD_DATADIR/ibdata1 $MYSQLD_DATADIR/ibdata1.bak
--copy_file $MYSQLD_DATADIR/ib_logfile0 $MYSQLD_DATADIR/ib_logfile0.bak
perl;
use IO::Handle;
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
my $polynomial = 0x82f63b78; # CRC-32C
my $algo = $ENV{ALGO};
die "Unsupported innodb_checksum_algorithm=$algo\n" unless $algo =~ /crc32/;
my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
my $page_size = $ENV{INNODB_PAGE_SIZE};
my $page;
do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
open(FILE, "+<", $fname) or die;
sysseek(FILE, ($page_size/2), 0);
syswrite(FILE, chr(0) x ($page_size/2));
sysseek(FILE, 3*$page_size, 0);
sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
sysseek(FILE, 3*$page_size, 0)||die "Unable to seek $fname\n";
my $corrupted = $page;
# Set FIL_PAGE_LSN to the maximum
substr($corrupted, 16, 8) = chr(255) x 8;
substr($corrupted, $page_size - 8, 8) = chr(255) x 8;
if ($algo =~ /full_crc32/)
{
my $ck = mycrc32(substr($corrupted, 0, $page_size - 4), 0, $polynomial);
substr($corrupted, $page_size - 4, 4) = pack("N", $ck);
}
else
{
# Replace the innodb_checksum_algorithm=crc32 checksum
my $ck= pack("N",
mycrc32(substr($corrupted, 4, 22), 0, $polynomial) ^
mycrc32(substr($corrupted_, 38, $page_size - 38 - 8), 0,
$polynomial));
substr ($corrupted, 0, 4) = $ck;
substr ($corrupted, $page_size - 8, 4) = $ck;
}
syswrite(FILE, $corrupted);
close FILE;
# Change the flag offset of page 0 in doublewrite buffer
open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n";
sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n";
sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n";
my($magic,$d1,$d2)=unpack "NNN", $_;
die "magic=$magic, $d1, $d2\n" unless $magic == 536853855 && $d2 >= $d1 + 64;
sysseek(FILE, $d1 * $page_size, 0)||die "Unable to seek ibdata1\n";
# Find the page in the doublewrite buffer
for (my $d = $d1; $d < $d2 + 64; $d++)
{
sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
next unless $_ eq $page;
sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n";
# Write buggy FSP_SPACE_FLAGS to the doublewrite buffer for page
my $badflags = 0x0006FFFF;
substr ($_, 54, 4) = pack("N", $badflags);
if ($algo =~ /full_crc32/)
{
my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial);
substr($_, $page_size - 4, 4) = pack("N", $ck);
}
else
{
# Replace the innodb_checksum_algorithm=crc32 checksum
my $ck= pack("N",
mycrc32(substr($_, 4, 22), 0, $polynomial) ^
mycrc32(substr($_, 38, $page_size - 38 - 8), 0,
$polynomial));
substr ($_, 0, 4) = $ck;
substr ($_, $page_size - 8, 4) = $ck;
}
syswrite(FILE, $_, $page_size)==$page_size||die;
close(FILE);
exit 0;
}
die "Did not find the page in the doublewrite buffer ($d1,$d2)\n";
EOF
--source include/start_mysqld.inc
let SEARCH_PATTERN=InnoDB: Recovered page \\[page id: space=[1-9][0-9]*, page number=0\\];
--source include/search_pattern_in_file.inc
let SEARCH_PATTERN=InnoDB: The log was only scanned up to \\d+, while the current LSN at the time of the latest checkpoint \\d+ was 0 and the maximum LSN on a data page was 18446744073709551615!
--source include/search_pattern_in_file.inc
--error ER_XAER_NOTA
XA ROLLBACK 'x';
let $shutdown_timeout=0;
--source include/shutdown_mysqld.inc
let $shutdown_timeout=;
# Corrupt the file in a better way.
--remove_file $MYSQLD_DATADIR/ibdata1
--remove_file $MYSQLD_DATADIR/ib_logfile0
--move_file $MYSQLD_DATADIR/ibdata1.bak $MYSQLD_DATADIR/ibdata1
--move_file $MYSQLD_DATADIR/ib_logfile0.bak $MYSQLD_DATADIR/ib_logfile0
perl;
use IO::Handle;
my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
my $page_size = $ENV{INNODB_PAGE_SIZE};
open(FILE, "+<", $fname) or die;
sysseek(FILE, ($page_size/2), 0);
syswrite(FILE, chr(0) x ($page_size/2));
sysseek(FILE, 3*$page_size, 0);
syswrite(FILE, chr(0) x ($page_size/2));
close FILE;
EOF
--source include/start_mysqld.inc
check table t1;
select f1, f2 from t1;
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0,innodb_max_dirty_pages_pct=0;
let $wait_condition =
SELECT variable_value = 0
FROM information_schema.global_status
WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY';
--source include/wait_condition.inc
SET GLOBAL innodb_max_dirty_pages_pct=99;
--source ../include/no_checkpoint_start.inc
XA ROLLBACK 'x';
FLUSH TABLE t1 FOR EXPORT;
# If we are skipping the test at this point due to an unexpected
# checkpoint, we will already have tested a part of this functionality.
--let CLEANUP_IF_CHECKPOINT=drop table t1;
--source ../include/no_checkpoint_end.inc
# Zero out the first page in file and try to recover from dblwr
perl;
use IO::Handle;
open(FILE, "+<", "$ENV{'MYSQLD_DATADIR'}test/t1.ibd") or die;
syswrite(FILE, chr(0) x $ENV{INNODB_PAGE_SIZE});
close FILE;
EOF
--source include/start_mysqld.inc
let SEARCH_PATTERN=InnoDB: Recovered page \\[page id: space=[1-9][0-9]*, page number=[03]\\];
--source include/search_pattern_in_file.inc
check table t1;
select f1, f2 from t1;
drop table t1;
--echo # End of 10.5 tests