mirror of
https://github.com/MariaDB/server.git
synced 2025-04-17 20:55:45 +02:00
MDEV-33295 innodb.doublewrite occasionally fails
When the first attempt of XA ROLLBACK is expected to fail, some recovered changes could be written back through the doublewrite buffer. Should that happen, the next recovery attempt (after mangling the data file t1.ibd further) could fail because no copy of the affected pages would be available in the doublewrite buffer. To prevent this from happening, ensure that the doublewrite buffer will not be used and no log checkpoint occurs during the previous failed recovery attempt. Also, let a successful XA ROLLBACK serve the additional purpose of freeing a BLOB page and therefore rewriting page 0, which we must then be able to recover despite induced corruption. In the last restart step, we will tolerate an unexpected checkpoint, because one is frequently occurring on FreeBSD and AIX, despite our efforts to force a buffer pool flush before each "no checkpoint" section.
This commit is contained in:
parent
9389428380
commit
900bbbe4a8
3 changed files with 38 additions and 28 deletions
mysql-test/suite/innodb
|
@ -11,9 +11,11 @@ insert into t1 values(5, repeat('.',12));
|
|||
commit work;
|
||||
SET GLOBAL innodb_fast_shutdown = 0;
|
||||
# restart
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0,innodb_max_dirty_pages_pct=0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=99;
|
||||
connect dml,localhost,root,,;
|
||||
XA START 'x';
|
||||
insert into t1 values (6, repeat('%', @@innodb_page_size/2));
|
||||
insert into t1 values(6, repeat('%', @@innodb_page_size/2));
|
||||
XA END 'x';
|
||||
XA PREPARE 'x';
|
||||
disconnect dml;
|
||||
|
@ -23,7 +25,6 @@ flush table t1 for export;
|
|||
# restart
|
||||
FOUND 1 /InnoDB: Recovered page \[page id: space=[1-9][0-9]*, page number=0\]/ in mysqld.1.err
|
||||
# restart
|
||||
XA ROLLBACK 'x';
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
|
@ -34,18 +35,13 @@ f1 f2
|
|||
3 ////////////
|
||||
4 ------------
|
||||
5 ............
|
||||
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;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0,innodb_max_dirty_pages_pct=0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=99;
|
||||
XA ROLLBACK 'x';
|
||||
FLUSH TABLE t1 FOR EXPORT;
|
||||
# Kill the server
|
||||
# restart
|
||||
FOUND 4 /InnoDB: Recovered page \[page id: space=[1-9][0-9]*, page number=[03]\]/ in mysqld.1.err
|
||||
XA ROLLBACK 'x';
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
[strict_crc32]
|
||||
--innodb-checksum-algorithm=strict_crc32
|
||||
--innodb-use-atomic-writes=0
|
||||
--innodb-undo-tablespaces=0
|
||||
|
||||
[strict_full_crc32]
|
||||
--innodb-checksum-algorithm=strict_full_crc32
|
||||
--innodb-use-atomic-writes=0
|
||||
--innodb-undo-tablespaces=0
|
||||
|
|
|
@ -42,13 +42,17 @@ commit work;
|
|||
SET GLOBAL innodb_fast_shutdown = 0;
|
||||
let $shutdown_timeout=;
|
||||
--source include/restart_mysqld.inc
|
||||
# Ensure that buf_flush_page_cleaner() has woken up from its
|
||||
# first my_cond_timedwait() and gone idle.
|
||||
sleep 1;
|
||||
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));
|
||||
insert into t1 values(6, repeat('%', @@innodb_page_size/2));
|
||||
XA END 'x';
|
||||
XA PREPARE 'x';
|
||||
disconnect dml;
|
||||
|
@ -56,10 +60,12 @@ connection default;
|
|||
|
||||
flush table t1 for export;
|
||||
|
||||
let $restart_parameters=;
|
||||
--let CLEANUP_IF_CHECKPOINT=drop table t1, unexpected_checkpoint;
|
||||
--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";
|
||||
|
@ -148,6 +154,12 @@ 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";
|
||||
|
@ -160,22 +172,23 @@ syswrite(FILE, chr(0) x ($page_size/2));
|
|||
close FILE;
|
||||
EOF
|
||||
--source include/start_mysqld.inc
|
||||
XA ROLLBACK 'x';
|
||||
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
|
||||
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;
|
||||
XA ROLLBACK 'x';
|
||||
FLUSH TABLE t1 FOR EXPORT;
|
||||
|
||||
flush table t1 for export;
|
||||
|
||||
let $restart_parameters=;
|
||||
# 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
|
||||
|
@ -189,7 +202,6 @@ 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
|
||||
XA ROLLBACK 'x';
|
||||
check table t1;
|
||||
select f1, f2 from t1;
|
||||
drop table t1;
|
||||
|
|
Loading…
Add table
Reference in a new issue