mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-32242 innodb.doublewrite test case always gets skipped
- Split the doublewrite test into two test (doublewrite,
doublewrite_debug) to reduce the execution time of the test
- Removed big_test tag for the newly added test case
- Made doublewrite test as non-debug test
- Added search pattern to make sure that InnoDB uses doublewrite buffer
- Replaced all kill_mysqld.inc with shutdown_mysqld.inc and
zero shutdown timeout
- Removed the case where fsp_flags got corrupted. Because from commit
3da5d047b8
(MDEV-31851) onwards,
doublewrite buffer removes the conversion the fsp flags from buggy
10.1 format
Thanks to Marko Mäkelä for providing the non-debug test
This commit is contained in:
@ -1,22 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY
|
# MDEV-32242 innodb.doublewrite test case always is skipped
|
||||||
# Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST
|
|
||||||
# PAGE OF SYSTEM TABLESPACE
|
|
||||||
#
|
#
|
||||||
SET GLOBAL innodb_fast_shutdown = 0;
|
|
||||||
# restart
|
|
||||||
show variables like 'innodb_doublewrite';
|
|
||||||
Variable_name Value
|
|
||||||
innodb_doublewrite ON
|
|
||||||
show variables like 'innodb_fil_make_page_dirty_debug';
|
|
||||||
Variable_name Value
|
|
||||||
innodb_fil_make_page_dirty_debug 0
|
|
||||||
show variables like 'innodb_saved_page_number_debug';
|
|
||||||
Variable_name Value
|
|
||||||
innodb_saved_page_number_debug 0
|
|
||||||
connect stop_purge,localhost,root,,;
|
|
||||||
START TRANSACTION WITH CONSISTENT SNAPSHOT;
|
|
||||||
connection default;
|
|
||||||
create table t1 (f1 int primary key, f2 blob) engine=innodb;
|
create table t1 (f1 int primary key, f2 blob) engine=innodb;
|
||||||
start transaction;
|
start transaction;
|
||||||
insert into t1 values(1, repeat('#',12));
|
insert into t1 values(1, repeat('#',12));
|
||||||
@ -25,29 +9,20 @@ insert into t1 values(3, repeat('/',12));
|
|||||||
insert into t1 values(4, repeat('-',12));
|
insert into t1 values(4, repeat('-',12));
|
||||||
insert into t1 values(5, repeat('.',12));
|
insert into t1 values(5, repeat('.',12));
|
||||||
commit work;
|
commit work;
|
||||||
# ---------------------------------------------------------------
|
SET GLOBAL innodb_fast_shutdown = 0;
|
||||||
# Test Begin: Test if recovery works if first page of user
|
|
||||||
# tablespace is full of zeroes.
|
|
||||||
select space from information_schema.innodb_sys_tables
|
|
||||||
where name = 'test/t1' into @space_id;
|
|
||||||
Warnings:
|
|
||||||
Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 12));
|
|
||||||
# Ensure that dirty pages of table t1 are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# 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;
|
|
||||||
# Ensure that dirty pages of table t1 are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
disconnect stop_purge;
|
|
||||||
# Make the first page (page_no=0) of the user tablespace
|
|
||||||
# full of zeroes.
|
|
||||||
#
|
|
||||||
# MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer.
|
|
||||||
# restart
|
# restart
|
||||||
|
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;
|
||||||
|
# restart
|
||||||
|
FOUND 1 /InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile/ in mysqld.1.err
|
||||||
|
FOUND 1 /InnoDB: Recovered page \[page id: space=[1-9][0-9]*, page number=3\]/ in mysqld.1.err
|
||||||
|
XA ROLLBACK 'x';
|
||||||
check table t1;
|
check table t1;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
@ -58,216 +33,5 @@ f1 f2
|
|||||||
3 ////////////
|
3 ////////////
|
||||||
4 ------------
|
4 ------------
|
||||||
5 ............
|
5 ............
|
||||||
# Test End
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Test Begin: Test if recovery works if first page of user
|
|
||||||
# tablespace is corrupted.
|
|
||||||
select space from information_schema.innodb_sys_tables
|
|
||||||
where name = 'test/t1' into @space_id;
|
|
||||||
Warnings:
|
|
||||||
Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
|
|
||||||
# Ensure that dirty pages of table t1 is flushed.
|
|
||||||
flush tables t1 for export;
|
|
||||||
unlock tables;
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 12));
|
|
||||||
# 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;
|
|
||||||
# Ensure that dirty pages of table t1 are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
# Corrupt the first page (page_no=0) of the user tablespace.
|
|
||||||
# restart
|
|
||||||
check table t1;
|
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
select f1, f2 from t1;
|
|
||||||
f1 f2
|
|
||||||
1 ############
|
|
||||||
2 ++++++++++++
|
|
||||||
3 ////////////
|
|
||||||
4 ------------
|
|
||||||
5 ............
|
|
||||||
# Test End
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Test Begin: Test if recovery works if 2nd page of user
|
|
||||||
# tablespace is full of zeroes.
|
|
||||||
select space from information_schema.innodb_sys_tables
|
|
||||||
where name = 'test/t1' into @space_id;
|
|
||||||
Warnings:
|
|
||||||
Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
|
|
||||||
# Ensure that dirty pages of table t1 is flushed.
|
|
||||||
flush tables t1 for export;
|
|
||||||
unlock tables;
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 400));
|
|
||||||
# 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;
|
|
||||||
# Ensure that dirty pages of table t1 are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
# Make the 2nd page (page_no=1) of the tablespace all zeroes.
|
|
||||||
# restart
|
|
||||||
check table t1;
|
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
select f1, f2 from t1;
|
|
||||||
f1 f2
|
|
||||||
1 ############
|
|
||||||
2 ++++++++++++
|
|
||||||
3 ////////////
|
|
||||||
4 ------------
|
|
||||||
5 ............
|
|
||||||
# Test End
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Test Begin: Test if recovery works if 2nd page of user
|
|
||||||
# tablespace is corrupted.
|
|
||||||
select space from information_schema.innodb_sys_tables
|
|
||||||
where name = 'test/t1' into @space_id;
|
|
||||||
Warnings:
|
|
||||||
Warning 1287 '<select expression> INTO <destination>;' is deprecated and will be removed in a future release. Please use 'SELECT <select list> INTO <destination> FROM...' instead
|
|
||||||
# Ensure that dirty pages of table t1 is flushed.
|
|
||||||
flush tables t1 for export;
|
|
||||||
unlock tables;
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 400));
|
|
||||||
# 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;
|
|
||||||
# Ensure that the dirty pages of table t1 are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
# Corrupt the 2nd page (page_no=1) of the user tablespace.
|
|
||||||
# restart
|
|
||||||
check table t1;
|
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
select f1, f2 from t1;
|
|
||||||
f1 f2
|
|
||||||
1 ############
|
|
||||||
2 ++++++++++++
|
|
||||||
3 ////////////
|
|
||||||
4 ------------
|
|
||||||
5 ............
|
|
||||||
# Test End
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Test Begin: Test if recovery works if first page of
|
|
||||||
# system tablespace is full of zeroes.
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 400));
|
|
||||||
# Ensure that all dirty pages in the system are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# 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;
|
|
||||||
# Ensure that the dirty page of system tablespace is also flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
# Make the first page (page_no=0) of the system tablespace
|
|
||||||
# all zeroes.
|
|
||||||
# restart
|
|
||||||
check table t1;
|
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
select f1, f2 from t1;
|
|
||||||
f1 f2
|
|
||||||
1 ############
|
|
||||||
2 ++++++++++++
|
|
||||||
3 ////////////
|
|
||||||
4 ------------
|
|
||||||
5 ............
|
|
||||||
# Test End
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Test Begin: Test if recovery works if first page of
|
|
||||||
# system tablespace is corrupted.
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 400));
|
|
||||||
# Ensure that all dirty pages in the system are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# 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;
|
|
||||||
# Ensure that the dirty page of system tablespace is also flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
# Corrupt the first page (page_no=0) of the system tablespace.
|
|
||||||
# restart
|
|
||||||
check table t1;
|
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
select f1, f2 from t1;
|
|
||||||
f1 f2
|
|
||||||
1 ############
|
|
||||||
2 ++++++++++++
|
|
||||||
3 ////////////
|
|
||||||
4 ------------
|
|
||||||
5 ............
|
|
||||||
# Test End
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Test Begin: Test if recovery works if 2nd page of
|
|
||||||
# system tablespace is full of zeroes.
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 400));
|
|
||||||
# Ensure that all dirty pages in the system are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# 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;
|
|
||||||
# Ensure that the dirty page of system tablespace is also flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
# Make the 2nd page (page_no=1) of the system tablespace
|
|
||||||
# all zeroes.
|
|
||||||
# restart
|
|
||||||
check table t1;
|
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
select f1, f2 from t1;
|
|
||||||
f1 f2
|
|
||||||
1 ############
|
|
||||||
2 ++++++++++++
|
|
||||||
3 ////////////
|
|
||||||
4 ------------
|
|
||||||
5 ............
|
|
||||||
# Test End
|
|
||||||
# ---------------------------------------------------------------
|
|
||||||
# Test Begin: Test if recovery works if 2nd page of
|
|
||||||
# system tablespace is corrupted.
|
|
||||||
begin;
|
|
||||||
insert into t1 values (6, repeat('%', 400));
|
|
||||||
# Ensure that all dirty pages in the system are flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# 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;
|
|
||||||
# Ensure that the dirty page of system tablespace is also flushed.
|
|
||||||
set global innodb_buf_flush_list_now = 1;
|
|
||||||
# Kill the server
|
|
||||||
# Make the 2nd page (page_no=1) of the system tablespace
|
|
||||||
# all zeroes.
|
|
||||||
# restart
|
|
||||||
check table t1;
|
|
||||||
Table Op Msg_type Msg_text
|
|
||||||
test.t1 check status OK
|
|
||||||
FOUND 1 /InnoDB: .*test.t1\.ibd/ in mysqld.1.err
|
|
||||||
select f1, f2 from t1;
|
|
||||||
f1 f2
|
|
||||||
1 ############
|
|
||||||
2 ++++++++++++
|
|
||||||
3 ////////////
|
|
||||||
4 ------------
|
|
||||||
5 ............
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
# End of 10.5 tests
|
||||||
# MDEV-12600 crash during install_db with innodb_page_size=32K
|
|
||||||
# and ibdata1=3M
|
|
||||||
#
|
|
||||||
# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend
|
|
||||||
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
|
||||||
WHERE engine = 'innodb'
|
|
||||||
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
|
||||||
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
|
||||||
FOUND 1 /\[ERROR\] InnoDB: Cannot create doublewrite buffer/ in mysqld.1.err
|
|
||||||
# restart
|
|
||||||
|
92
mysql-test/suite/innodb/r/doublewrite_debug.result
Normal file
92
mysql-test/suite/innodb/r/doublewrite_debug.result
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#
|
||||||
|
# Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY
|
||||||
|
# Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST
|
||||||
|
# PAGE OF SYSTEM TABLESPACE
|
||||||
|
#
|
||||||
|
show variables like 'innodb_doublewrite';
|
||||||
|
Variable_name Value
|
||||||
|
innodb_doublewrite ON
|
||||||
|
show variables like 'innodb_fil_make_page_dirty_debug';
|
||||||
|
Variable_name Value
|
||||||
|
innodb_fil_make_page_dirty_debug 0
|
||||||
|
show variables like 'innodb_saved_page_number_debug';
|
||||||
|
Variable_name Value
|
||||||
|
innodb_saved_page_number_debug 0
|
||||||
|
create table t1 (f1 int primary key, f2 blob) 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;
|
||||||
|
# Test Begin: Test if recovery works if 1st page and 2nd page
|
||||||
|
# of system tablespace is full of zeroes.
|
||||||
|
SET GLOBAL innodb_fast_shutdown = 0;
|
||||||
|
# restart
|
||||||
|
begin;
|
||||||
|
insert into t1 values (6, repeat('%', 400));
|
||||||
|
# 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;
|
||||||
|
# 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;
|
||||||
|
set global innodb_buf_flush_list_now = 1;
|
||||||
|
# Make the 1st page (page_no=0) and 2nd page (page_no=1)
|
||||||
|
# of the system tablespace all zeroes.
|
||||||
|
# restart
|
||||||
|
FOUND 1 /InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile/ in mysqld.1.err
|
||||||
|
FOUND 1 /InnoDB: Recovered page \[page id: space=0, page number=1\]/ in mysqld.1.err
|
||||||
|
check table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check status OK
|
||||||
|
select f1, f2 from t1;
|
||||||
|
f1 f2
|
||||||
|
1 ############
|
||||||
|
2 ++++++++++++
|
||||||
|
3 ////////////
|
||||||
|
4 ------------
|
||||||
|
5 ............
|
||||||
|
# Test End
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Test Begin: Test if recovery works if 1st page of
|
||||||
|
# system tablespace is corrupted and 2nd page as corrupted.
|
||||||
|
set global innodb_log_checkpoint_now = 1;
|
||||||
|
begin;
|
||||||
|
insert into t1 values (6, repeat('%', 400));
|
||||||
|
# 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;
|
||||||
|
# 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;
|
||||||
|
set global innodb_buf_flush_list_now = 1;
|
||||||
|
# Corrupt the 1st page (page_no=0) and 2nd page of the system tablespace.
|
||||||
|
# restart
|
||||||
|
FOUND 2 /InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile/ in mysqld.1.err
|
||||||
|
FOUND 2 /InnoDB: Recovered page \[page id: space=0, page number=1\]/ in mysqld.1.err
|
||||||
|
check table t1;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check status OK
|
||||||
|
select f1, f2 from t1;
|
||||||
|
f1 f2
|
||||||
|
1 ############
|
||||||
|
2 ++++++++++++
|
||||||
|
3 ////////////
|
||||||
|
4 ------------
|
||||||
|
5 ............
|
||||||
|
drop table t1;
|
||||||
|
# Test End
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# MDEV-12600 crash during install_db with innodb_page_size=32K
|
||||||
|
# and ibdata1=3M
|
||||||
|
#
|
||||||
|
# restart: --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/doublewrite --innodb-data-file-path=ibdata1:1M;ibdata2:1M:autoextend
|
||||||
|
SELECT * FROM INFORMATION_SCHEMA.ENGINES
|
||||||
|
WHERE engine = 'innodb'
|
||||||
|
AND support IN ('YES', 'DEFAULT', 'ENABLED');
|
||||||
|
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
|
||||||
|
FOUND 1 /\[ERROR\] InnoDB: Cannot create doublewrite buffer/ in mysqld.1.err
|
||||||
|
# restart
|
@ -1,17 +1,11 @@
|
|||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug #17335427 INNODB CAN NOT USE THE DOUBLEWRITE BUFFER PROPERLY
|
--echo # MDEV-32242 innodb.doublewrite test case always is skipped
|
||||||
--echo # Bug #18144349 INNODB CANNOT USE THE DOUBLEWRITE BUFFER FOR THE FIRST
|
|
||||||
--echo # PAGE OF SYSTEM TABLESPACE
|
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
--source include/innodb_page_size.inc
|
--source include/innodb_page_size.inc
|
||||||
--source include/have_debug.inc
|
|
||||||
--source include/not_embedded.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
|
--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: 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: adjusting FSP_SPACE_FLAGS");
|
||||||
@ -22,22 +16,14 @@ 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: A bad Space ID was found in datafile");
|
||||||
call mtr.add_suppression("InnoDB: Checksum mismatch 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("InnoDB: Inconsistent tablespace ID in .*t1\\.ibd");
|
||||||
|
call mtr.add_suppression("\\[Warning\\] Found 1 prepared XA transactions");
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
--source include/restart_mysqld.inc
|
|
||||||
|
|
||||||
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
|
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
|
||||||
let MYSQLD_DATADIR=`select @@datadir`;
|
let MYSQLD_DATADIR=`select @@datadir`;
|
||||||
let ALGO=`select @@innodb_checksum_algorithm`;
|
let ALGO=`select @@innodb_checksum_algorithm`;
|
||||||
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
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;
|
create table t1 (f1 int primary key, f2 blob) engine=innodb;
|
||||||
|
|
||||||
start transaction;
|
start transaction;
|
||||||
@ -48,35 +34,24 @@ insert into t1 values(4, repeat('-',12));
|
|||||||
insert into t1 values(5, repeat('.',12));
|
insert into t1 values(5, repeat('.',12));
|
||||||
commit work;
|
commit work;
|
||||||
|
|
||||||
--echo # ---------------------------------------------------------------
|
# Slow shutdown and restart to make sure ibuf merge is finished
|
||||||
--echo # Test Begin: Test if recovery works if first page of user
|
SET GLOBAL innodb_fast_shutdown = 0;
|
||||||
--echo # tablespace is full of zeroes.
|
let $shutdown_timeout=;
|
||||||
|
--source include/restart_mysqld.inc
|
||||||
|
|
||||||
select space from information_schema.innodb_sys_tables
|
connect (dml,localhost,root,,);
|
||||||
where name = 'test/t1' into @space_id;
|
XA START 'x';
|
||||||
|
insert into t1 values (6, repeat('%', @@innodb_page_size/2));
|
||||||
|
XA END 'x';
|
||||||
|
XA PREPARE 'x';
|
||||||
|
disconnect dml;
|
||||||
|
connection default;
|
||||||
|
|
||||||
begin;
|
flush table t1 for export;
|
||||||
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;
|
|
||||||
|
|
||||||
--source ../include/no_checkpoint_start.inc
|
let $restart_parameters=;
|
||||||
|
let $shutdown_timeout=0;
|
||||||
--echo # Make the first page dirty for table t1
|
--source include/shutdown_mysqld.inc
|
||||||
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;
|
|
||||||
|
|
||||||
--let CLEANUP_IF_CHECKPOINT=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;
|
perl;
|
||||||
use IO::Handle;
|
use IO::Handle;
|
||||||
@ -90,16 +65,15 @@ my $page_size = $ENV{INNODB_PAGE_SIZE};
|
|||||||
my $page;
|
my $page;
|
||||||
do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
|
do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
|
||||||
open(FILE, "+<", $fname) or die;
|
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";
|
sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n";
|
||||||
my $page1 = $page;
|
sysseek(FILE, 3*$page_size, 0)||die "Unable to seek $fname\n";
|
||||||
substr($page1, 34, 4) = pack("N", 0);
|
syswrite(FILE, chr(0) x ($page_size/2));
|
||||||
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;
|
|
||||||
close FILE;
|
close FILE;
|
||||||
|
|
||||||
|
# Change the flag offset of page 0 in doublewrite buffer
|
||||||
open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n";
|
open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n";
|
||||||
sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek 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";
|
sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n";
|
||||||
@ -112,28 +86,23 @@ for (my $d = $d1; $d < $d2 + 64; $d++)
|
|||||||
sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
|
sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n";
|
||||||
next unless $_ eq $page;
|
next unless $_ eq $page;
|
||||||
sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n";
|
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
|
# Write buggy FSP_SPACE_FLAGS to the doublewrite buffer for page
|
||||||
my($flags) = unpack "x[54]N", $_;
|
my $badflags = 0x0006FFFF;
|
||||||
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
|
|
||||||
|
|
||||||
substr ($_, 54, 4) = pack("N", $badflags);
|
substr ($_, 54, 4) = pack("N", $badflags);
|
||||||
if ($algo =~ /full_crc32/)
|
if ($algo =~ /full_crc32/)
|
||||||
{
|
{
|
||||||
my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial);
|
my $ck = mycrc32(substr($_, 0, $page_size - 4), 0, $polynomial);
|
||||||
substr($_, $page_size - 4, 4) = pack("N", $ck);
|
substr($_, $page_size - 4, 4) = pack("N", $ck);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
# Replace the innodb_checksum_algorithm=crc32 checksum
|
# Replace the innodb_checksum_algorithm=crc32 checksum
|
||||||
my $ck= pack("N",
|
my $ck= pack("N",
|
||||||
mycrc32(substr($_, 4, 22), 0, $polynomial) ^
|
mycrc32(substr($_, 4, 22), 0, $polynomial) ^
|
||||||
mycrc32(substr($_, 38, $page_size - 38 - 8), 0,
|
mycrc32(substr($_, 38, $page_size - 38 - 8), 0,
|
||||||
$polynomial));
|
$polynomial));
|
||||||
substr ($_, 0, 4) = $ck;
|
substr ($_, 0, 4) = $ck;
|
||||||
substr ($_, $page_size - 8, 4) = $ck;
|
substr ($_, $page_size - 8, 4) = $ck;
|
||||||
}
|
}
|
||||||
syswrite(FILE, $_, $page_size)==$page_size||die;
|
syswrite(FILE, $_, $page_size)==$page_size||die;
|
||||||
close(FILE);
|
close(FILE);
|
||||||
@ -143,323 +112,13 @@ die "Did not find the page in the doublewrite buffer ($d1,$d2)\n";
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
--source include/start_mysqld.inc
|
--source include/start_mysqld.inc
|
||||||
|
let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=[1-9][0-9]*, page number=0\] of datafile;
|
||||||
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 from information_schema.innodb_sys_tables
|
|
||||||
where name = 'test/t1' into @space_id;
|
|
||||||
|
|
||||||
--echo # Ensure that dirty pages of table t1 is flushed.
|
|
||||||
flush tables t1 for export;
|
|
||||||
unlock tables;
|
|
||||||
|
|
||||||
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 from information_schema.innodb_sys_tables
|
|
||||||
where name = 'test/t1' into @space_id;
|
|
||||||
|
|
||||||
--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
|
|
||||||
|
|
||||||
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 from information_schema.innodb_sys_tables
|
|
||||||
where name = 'test/t1' into @space_id;
|
|
||||||
|
|
||||||
--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 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;
|
|
||||||
|
|
||||||
--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'}/2);
|
|
||||||
close FILE;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
--source include/start_mysqld.inc
|
|
||||||
|
|
||||||
check table t1;
|
|
||||||
--let SEARCH_PATTERN= InnoDB: .*test.t1\\.ibd
|
|
||||||
--source include/search_pattern_in_file.inc
|
--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;
|
select f1, f2 from t1;
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
--echo #
|
--echo # End of 10.5 tests
|
||||||
--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
|
|
||||||
|
7
mysql-test/suite/innodb/t/doublewrite_debug.combinations
Normal file
7
mysql-test/suite/innodb/t/doublewrite_debug.combinations
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[strict_crc32]
|
||||||
|
--innodb-checksum-algorithm=strict_crc32
|
||||||
|
--innodb-use-atomic-writes=0
|
||||||
|
|
||||||
|
[strict_full_crc32]
|
||||||
|
--innodb-checksum-algorithm=strict_full_crc32
|
||||||
|
--innodb-use-atomic-writes=0
|
162
mysql-test/suite/innodb/t/doublewrite_debug.test
Normal file
162
mysql-test/suite/innodb/t/doublewrite_debug.test
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
--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 #
|
||||||
|
|
||||||
|
--source include/innodb_page_size.inc
|
||||||
|
--source include/have_debug.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");
|
||||||
|
--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;
|
||||||
|
|
||||||
|
show variables like 'innodb_doublewrite';
|
||||||
|
show variables like 'innodb_fil_make_page_dirty_debug';
|
||||||
|
show variables like 'innodb_saved_page_number_debug';
|
||||||
|
|
||||||
|
create table t1 (f1 int primary key, f2 blob) 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;
|
||||||
|
|
||||||
|
--echo # Test Begin: Test if recovery works if 1st page and 2nd page
|
||||||
|
--echo # of system tablespace is full of zeroes.
|
||||||
|
|
||||||
|
# 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
|
||||||
|
begin;
|
||||||
|
insert into t1 values (6, repeat('%', 400));
|
||||||
|
|
||||||
|
--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 # 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;
|
||||||
|
|
||||||
|
set global innodb_buf_flush_list_now = 1;
|
||||||
|
let $shutdown_timeout=0;
|
||||||
|
--source include/shutdown_mysqld.inc
|
||||||
|
|
||||||
|
--echo # Make the 1st page (page_no=0) and 2nd page (page_no=1)
|
||||||
|
--echo # of the system tablespace 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'});
|
||||||
|
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=0, page number=0\] of datafile;
|
||||||
|
--source include/search_pattern_in_file.inc
|
||||||
|
|
||||||
|
let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=0, page number=1\];
|
||||||
|
--source include/search_pattern_in_file.inc
|
||||||
|
|
||||||
|
check table t1;
|
||||||
|
select f1, f2 from t1;
|
||||||
|
|
||||||
|
--echo # Test End
|
||||||
|
--echo # ---------------------------------------------------------------
|
||||||
|
--echo # Test Begin: Test if recovery works if 1st page of
|
||||||
|
--echo # system tablespace is corrupted and 2nd page as corrupted.
|
||||||
|
|
||||||
|
set global innodb_log_checkpoint_now = 1;
|
||||||
|
begin;
|
||||||
|
insert into t1 values (6, repeat('%', 400));
|
||||||
|
|
||||||
|
--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 # 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;
|
||||||
|
|
||||||
|
set global innodb_buf_flush_list_now = 1;
|
||||||
|
let $shutdown_timeout=0;
|
||||||
|
--source include/shutdown_mysqld.inc
|
||||||
|
|
||||||
|
--echo # Corrupt the 1st page (page_no=0) and 2nd page 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);
|
||||||
|
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
|
||||||
|
|
||||||
|
let SEARCH_PATTERN=InnoDB: Restoring page \[page id: space=0, page number=0\] of datafile;
|
||||||
|
--source include/search_pattern_in_file.inc
|
||||||
|
|
||||||
|
let SEARCH_PATTERN=InnoDB: Recovered page \[page id: space=0, page number=1\];
|
||||||
|
--source include/search_pattern_in_file.inc
|
||||||
|
|
||||||
|
check table t1;
|
||||||
|
select f1, f2 from t1;
|
||||||
|
drop table t1;
|
||||||
|
let $shutdown_timeout=;
|
||||||
|
--echo # Test End
|
||||||
|
--echo # ---------------------------------------------------------------
|
||||||
|
--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
|
@ -18326,11 +18326,15 @@ static
|
|||||||
void
|
void
|
||||||
buf_flush_list_now_set(THD*, st_mysql_sys_var*, void*, const void* save)
|
buf_flush_list_now_set(THD*, st_mysql_sys_var*, void*, const void* save)
|
||||||
{
|
{
|
||||||
if (*(my_bool*) save) {
|
if (!*(my_bool*) save)
|
||||||
mysql_mutex_unlock(&LOCK_global_system_variables);
|
return;
|
||||||
buf_flush_sync();
|
const uint s= srv_fil_make_page_dirty_debug;
|
||||||
mysql_mutex_lock(&LOCK_global_system_variables);
|
mysql_mutex_unlock(&LOCK_global_system_variables);
|
||||||
}
|
if (s)
|
||||||
|
buf_flush_sync();
|
||||||
|
else
|
||||||
|
while (buf_flush_list_space(fil_system.sys_space, nullptr));
|
||||||
|
mysql_mutex_lock(&LOCK_global_system_variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Override current MERGE_THRESHOLD setting for all indexes at dictionary
|
/** Override current MERGE_THRESHOLD setting for all indexes at dictionary
|
||||||
|
Reference in New Issue
Block a user