Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
11.4, 11.8, 12.3
-
Can result in hang or crash
-
Crash recovery could hang after reporting page corruption in the InnoDB system tablespace or an undo tablespace.
Description
This originally came up in MDEV-42009.
If the dictionary header page is corrupted when log records are being applied to it, InnoDB would hang in an infinite loop. The following test case reproduces this:
--source include/have_innodb.inc
|
--source include/not_embedded.inc
|
--source include/have_debug.inc # for OPT_PAGE_CHECKSUM
|
|
|
let INNODB_PAGE_SIZE=`select @@innodb_page_size`; |
let ALGO=`select @@innodb_checksum_algorithm`; |
SET GLOBAL innodb_log_checkpoint_now=ON; |
CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB; |
--source include/kill_mysqld.inc
|
|
|
perl;
|
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl"; |
my $polynomial = 0x82f63b78; # CRC-32C
|
my $algo = $ENV{ALGO};
|
my $ps = $ENV{INNODB_PAGE_SIZE};
|
my $file = "$ENV{MARIADB_DATADIR}/ibdata1"; |
my $backup = "$ENV{MARIADB_DATADIR}/ibdata1.bak"; |
my $page;
|
open(FILE, "+<$file") || die "Unable to open $file"; |
binmode FILE;
|
sysseek(FILE, 7*$ps, 0) || die "Unable to seek $file\n"; |
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; |
open(BACKUP, ">$backup") || die "Unable to open $backup"; |
binmode BACKUP;
|
die "Unable to write $backup" unless syswrite(BACKUP, $page, $ps) == $ps; |
close(BACKUP) or die "close"; |
substr($page, 8, 8) = chr(170) x 8;
|
if ($algo =~ /full_crc32/) |
{
|
my $ck = mycrc32(substr($page, 0, $ps - 4), 0, $polynomial);
|
substr($page, $ps - 4, 4) = pack("N", $ck); |
}
|
else
|
{
|
# Replace the innodb_checksum_algorithm=crc32 checksum |
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, 7*$ps, 0) || die "Unable to seek $file\n"; |
syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; |
close FILE or die "close"; |
EOF
|
|
|
--source include/start_mysqld.inc
|
--error ER_UNKNOWN_STORAGE_ENGINE
|
SELECT * FROM t; |
|
|
perl;
|
my $file = "$ENV{MARIADB_DATADIR}/ibdata1"; |
my $backup = "$ENV{MARIADB_DATADIR}/ibdata1.bak"; |
my $ps = $ENV{INNODB_PAGE_SIZE};
|
my $page;
|
open(BACKUP, "<$backup") || die "Unable to open $backup"; |
binmode BACKUP;
|
die "Unable to read $backup" unless sysread(BACKUP, $page, $ps) == $ps; |
close(BACKUP) or die "close"; |
open(FILE, "+<$file") || die "Unable to open $file"; |
sysseek(FILE, 7*$ps, 0) || die "Unable to seek $file\n"; |
die "Unable to write $file" unless syswrite(FILE, $page, $ps) == $ps; |
close(FILE) or die "close"; |
EOF
|
|
|
--source include/restart_mysqld.inc
|
SELECT * FROM t; |
DROP TABLE t; |
--remove_file $MARIADB_DATADIR/ibdata1.bak |
I suspect that this regression was introduced by MDEV-32042, but I did not confirm that yet.
Attachments
Issue Links
- is caused by
-
MDEV-32042 Special handling of crash recovery in buf_page_get_gen() may cause overhead
-
- Closed
-
- relates to
-
MDEV-42040 Recovery ignores failure to apply log to a new page
-
- Open
-
-
MDEV-42009 Set GLOBAL innodb_log_archive=ON is not crash safe
-
- Closed
-