summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/innodb/t/doublewrite.test
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/suite/innodb/t/doublewrite.test')
-rw-r--r--mysql-test/suite/innodb/t/doublewrite.test429
1 files changed, 58 insertions, 371 deletions
diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test
index d8dac955..d7300990 100644
--- a/mysql-test/suite/innodb/t/doublewrite.test
+++ b/mysql-test/suite/innodb/t/doublewrite.test
@@ -1,17 +1,11 @@
+
--echo #
---echo # Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY
---echo # Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST
---echo # PAGE OF SYSTEM TABLESPACE
+--echo # MDEV-32242 innodb.doublewrite test case always is skipped
--echo #
--source include/innodb_page_size.inc
---source include/have_debug.inc
--source include/not_embedded.inc
-# This test is slow on buildbot.
---source include/big_test.inc
-# Slow shutdown and restart to make sure ibuf merge is finished
-SET GLOBAL innodb_fast_shutdown = 0;
--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");
@@ -22,23 +16,16 @@ call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registra
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:");
--enable_query_log
---source include/restart_mysqld.inc
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;
-show variables like 'innodb_doublewrite';
-show variables like 'innodb_fil_make_page_dirty_debug';
-show variables like 'innodb_saved_page_number_debug';
-
-connect (stop_purge,localhost,root,,);
-START TRANSACTION WITH CONSISTENT SNAPSHOT;
-connection default;
-
-create table t1 (f1 int primary key, f2 blob) engine=innodb stats_persistent=0;
+create table t1 (f1 int primary key, f2 blob) stats_persistent=0, engine=innodb;
start transaction;
insert into t1 values(1, repeat('#',12));
@@ -48,35 +35,24 @@ insert into t1 values(4, repeat('-',12));
insert into t1 values(5, repeat('.',12));
commit work;
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if first page of user
---echo # tablespace is full of zeroes.
-
-select space into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
-begin;
-insert into t1 values (6, repeat('%', 12));
---echo # Ensure that dirty pages of table t1 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
+# 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
--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;
---echo # Make the first page dirty for table t1
-set global innodb_saved_page_number_debug = 0;
-set global innodb_fil_make_page_dirty_debug = @space_id;
-
---echo # Ensure that dirty pages of table t1 are flushed.
-set global innodb_buf_flush_list_now = 1;
+flush table t1 for export;
---let CLEANUP_IF_CHECKPOINT=drop table t1;
+let $restart_parameters=;
+--let CLEANUP_IF_CHECKPOINT=XA COMMIT 'x';drop table t1;
--source ../include/no_checkpoint_end.inc
-disconnect stop_purge;
-
---echo # Make the first page (page_no=0) of the user tablespace
---echo # full of zeroes.
---echo #
---echo # MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer.
perl;
use IO::Handle;
@@ -90,16 +66,15 @@ 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";
-my $page1 = $page;
-substr($page1, 34, 4) = pack("N", 0);
-my $polynomial0 = 0x82f63b78; # CRC-32C
-my $ck0 = mycrc32(substr($page1, 0, ($page_size-4)), 0, $polynomial0);
-substr($page1, ($page_size - 4), 4) = pack("N", $ck0);
-sysseek(FILE, 0, 0)||die "Unable to seek $fname\n";
-die unless syswrite(FILE, $page1, $page_size) == $page_size;
+sysseek(FILE, 3*$page_size, 0)||die "Unable to seek $fname\n";
+syswrite(FILE, chr(0) x ($page_size/2));
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";
@@ -112,28 +87,23 @@ 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 MariaDB 10.1.x FSP_SPACE_FLAGS to the doublewrite buffer
- my($flags) = unpack "x[54]N", $_;
- my $badflags = ($flags & 0x3f);
- my $compression_level=6;
- $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16);
- $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE
-
+ # 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);
+ 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;
+ # 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);
@@ -143,325 +113,42 @@ die "Did not find the page in the doublewrite buffer ($d1,$d2)\n";
EOF
--source include/start_mysqld.inc
-
-check table t1;
-select f1, f2 from t1;
-
---echo # Test End
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if first page of user
---echo # tablespace is corrupted.
-
-select space into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
---echo # Ensure that dirty pages of table t1 is flushed.
-flush tables t1 for export;
-unlock tables;
-
-set global innodb_log_checkpoint_now=1;
-
-begin;
-insert into t1 values (6, repeat('%', 12));
-
---source ../include/no_checkpoint_start.inc
-
---echo # Make the first page dirty for table t1
-set global innodb_saved_page_number_debug = 0;
-set global innodb_fil_make_page_dirty_debug = @space_id;
-
---echo # Ensure that dirty pages of table t1 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/no_checkpoint_end.inc
-
---echo # Corrupt the first page (page_no=0) of the user tablespace.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
-my $page_size = $ENV{INNODB_PAGE_SIZE};
-open(FILE, "+<", $fname) or die;
-sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
-substr($page, 28, 4) = pack("N", 1000);
-sysseek(FILE, 0, 0)||die "Unable to seek $fname\n";
-die unless syswrite(FILE, $page, $page_size) == $page_size;
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-check table t1;
-select f1, f2 from t1;
-
---echo # Test End
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if 2nd page of user
---echo # tablespace is full of zeroes.
-
-select space into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
---echo # Ensure that dirty pages of table t1 is flushed.
-flush tables t1 for export;
-unlock tables;
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---source ../include/no_checkpoint_start.inc
-
---echo # Make the 2nd page dirty for table t1
-set global innodb_saved_page_number_debug = 1;
-set global innodb_fil_make_page_dirty_debug = @space_id;
-
---echo # Ensure that dirty pages of table t1 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/no_checkpoint_end.inc
-
---echo # Make the 2nd page (page_no=1) of the tablespace all zeroes.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
+let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile;
+--source include/search_pattern_in_file.inc
+let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=[1-9][0-9]*, page number=3\];
+--source include/search_pattern_in_file.inc
+XA ROLLBACK 'x';
check table t1;
select f1, f2 from t1;
---echo # Test End
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if 2nd page of user
---echo # tablespace is corrupted.
-
-select space into @space_id from information_schema.innodb_sys_tables
-where name = 'test/t1';
-
---echo # Ensure that dirty pages of table t1 is flushed.
-flush tables t1 for export;
-unlock tables;
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
--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;
---echo # Make the 2nd page dirty for table t1
-set global innodb_saved_page_number_debug = 1;
-set global innodb_fil_make_page_dirty_debug = @space_id;
-
---echo # Ensure that the dirty pages of table t1 are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/no_checkpoint_end.inc
-
---echo # Corrupt the 2nd page (page_no=1) of the user tablespace.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-check table t1;
-select f1, f2 from t1;
-
---echo # Test End
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if first page of
---echo # system tablespace is full of zeroes.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---echo # Make the first page dirty for system tablespace
-set global innodb_saved_page_number_debug = 0;
-set global innodb_fil_make_page_dirty_debug = 0;
-
---echo # Ensure that the dirty page of system tablespace is also flushed.
-# We do this after the transaction starts and all dirty pages have been flushed
-# already. So flushing of this specified dirty page will surely keep the
-# copy in doublewrite buffer, and no more writes to doublewrite buffer would
-# overwrite the copy. Thus, we can safely modify the original page when server
-# is down. So do the following testings.
-set global innodb_buf_flush_list_now = 1;
-
---source include/kill_mysqld.inc
-
---echo # Make the first page (page_no=0) of the system tablespace
---echo # all zeroes.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-check table t1;
-select f1, f2 from t1;
-
---echo # Test End
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if first page of
---echo # system tablespace is corrupted.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---echo # Make the first page dirty for system tablespace
-set global innodb_saved_page_number_debug = 0;
-set global innodb_fil_make_page_dirty_debug = 0;
-
---echo # Ensure that the dirty page of system tablespace is also flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/kill_mysqld.inc
-
---echo # Corrupt the first page (page_no=0) of the system tablespace.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-check table t1;
-select f1, f2 from t1;
-
---echo # Test End
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if 2nd page of
---echo # system tablespace is full of zeroes.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---echo # Make the second page dirty for system tablespace
-set global innodb_saved_page_number_debug = 1;
-set global innodb_fil_make_page_dirty_debug = 0;
-
---echo # Ensure that the dirty page of system tablespace is also flushed.
-set global innodb_buf_flush_list_now = 1;
-
---source include/kill_mysqld.inc
-
---echo # Make the 2nd page (page_no=1) of the system tablespace
---echo # all zeroes.
-perl;
-use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'});
-close FILE;
-EOF
-
---source include/start_mysqld.inc
-
-check table t1;
-select f1, f2 from t1;
-
---echo # Test End
---echo # ---------------------------------------------------------------
---echo # Test Begin: Test if recovery works if 2nd page of
---echo # system tablespace is corrupted.
-
-begin;
-insert into t1 values (6, repeat('%', 400));
-
---echo # Ensure that all dirty pages in the system are flushed.
-set global innodb_buf_flush_list_now = 1;
-
---echo # Make the second page dirty for system tablespace
-set global innodb_saved_page_number_debug = 1;
-set global innodb_fil_make_page_dirty_debug = 0;
-
---echo # Ensure that the dirty page of system tablespace is also flushed.
-set global innodb_buf_flush_list_now = 1;
+flush table t1 for export;
---source include/kill_mysqld.inc
+let $restart_parameters=;
+--source ../include/no_checkpoint_end.inc
---echo # Make the 2nd page (page_no=1) of the system tablespace
---echo # all zeroes.
+# Zero out the first page in file and try to recover from dblwr
perl;
use IO::Handle;
-my $fname= "$ENV{'MYSQLD_DATADIR'}ibdata1";
-open(FILE, "+<", $fname) or die;
-FILE->autoflush(1);
-binmode FILE;
-seek(FILE, $ENV{'INNODB_PAGE_SIZE'}, SEEK_SET);
-print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}/2);
+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
-
-check table t1;
---let SEARCH_PATTERN= InnoDB: .*test.t1\\.ibd
+let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile;
--source include/search_pattern_in_file.inc
-
+XA ROLLBACK 'x';
+check table t1;
select f1, f2 from t1;
-
drop table t1;
---echo #
---echo # MDEV-12600 crash during install_db with innodb_page_size=32K
---echo # and ibdata1=3M
---echo #
-let bugdir= $MYSQLTEST_VARDIR/tmp/doublewrite;
---mkdir $bugdir
-
-let $check_no_innodb=SELECT * FROM INFORMATION_SCHEMA.ENGINES
-WHERE engine = 'innodb'
-AND support IN ('YES', 'DEFAULT', 'ENABLED');
-
---let $ibp=--innodb-log-group-home-dir=$bugdir --innodb-data-home-dir=$bugdir
---let $ibd=$ibp --innodb-undo-tablespaces=0
---let $ibp=$ibp --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend
-
---let $restart_parameters= $ibp
---source include/restart_mysqld.inc
-eval $check_no_innodb;
---let SEARCH_PATTERN= \[ERROR\] InnoDB: Cannot create doublewrite buffer
---source include/search_pattern_in_file.inc
---let $restart_parameters=
---source include/restart_mysqld.inc
-
---remove_file $bugdir/ibdata1
---remove_file $bugdir/ibdata2
---remove_file $bugdir/ib_logfile0
---rmdir $bugdir
+--echo # End of 10.5 tests