Skip to content

Commit 993b8ed

Browse files
committed
MDEV-26933 InnoDB fails to detect page number mismatch
mtr_t::page_lock(): Validate the page number. ibuf_tree_root_get(): Remove assertions that became redundant. The assertions in btr_validate_level() are kind of redundant as well, but because they are ut_a(), they are also present in release builds, while the ones in mtr_t::page_lock() are only present in debug builds. btr_cur_position(): Do not duplicate an assertion that is part of page_cur_position(). dict_load_tablespace(): Introduce a new option DICT_ERR_IGNORE_TABLESPACE that will suppress loading a tablespace when a table is going to be dropped.
1 parent fdc4c3a commit 993b8ed

File tree

11 files changed

+35
-18
lines changed

11 files changed

+35
-18
lines changed

mysql-test/suite/innodb/r/alter_kill.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ InnoDB 0 transactions not purged
1111
connection default;
1212
# Cleanly shutdown mysqld
1313
disconnect con1;
14-
# Corrupt FIL_PAGE_OFFSET in bug16720368.ibd,
14+
# Corrupt FIL_PAGE_TYPE in bug16720368.ibd,
1515
# and recompute innodb_checksum_algorithm=crc32
1616
# restart
1717
SELECT COUNT(*) FROM bug16720368;

mysql-test/suite/innodb/t/alter_kill.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ connection default;
4343

4444
disconnect con1;
4545

46-
-- echo # Corrupt FIL_PAGE_OFFSET in bug16720368.ibd,
46+
-- echo # Corrupt FIL_PAGE_TYPE in bug16720368.ibd,
4747
-- echo # and recompute innodb_checksum_algorithm=crc32
4848
perl;
4949
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
@@ -56,7 +56,7 @@ die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
5656
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
5757
sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n";
5858
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
59-
substr($page,4,4)=pack("N",0xc001cafe);
59+
substr($page,24,2)='42';
6060
my $polynomial = 0x82f63b78; # CRC-32C
6161
if ($full_crc32)
6262
{
@@ -86,7 +86,7 @@ INSERT INTO bug16720368_1 VALUES(1);
8686
-- echo # Shut down the server to uncorrupt the data.
8787
-- source include/shutdown_mysqld.inc
8888

89-
# Uncorrupt the FIL_PAGE_OFFSET.
89+
# Uncorrupt the FIL_PAGE_TYPE.
9090
perl;
9191
do "$ENV{MTR_SUITE_DIR}/include/crc32.pl";
9292
my $file = "$ENV{MYSQLD_DATADIR}/test/bug16720368.ibd";
@@ -98,7 +98,7 @@ die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
9898
my $full_crc32 = unpack("N",substr($page,54,4)) & 0x10; # FIL_SPACE_FLAGS
9999
sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n";
100100
die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps;
101-
substr($page,4,4)=pack("N",3);
101+
substr($page,24,2)=pack("H*","45BF");
102102
my $polynomial = 0x82f63b78; # CRC-32C
103103
if ($full_crc32)
104104
{

mysql-test/suite/innodb/t/log_corruption.test

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,14 @@ my $body = pack("x[8]Nx[10]Nx[16312]", 768, 97937874);
5757
my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial);
5858
print OUT pack("N",$ck).$head.pack("x[12]").$body.pack("Nx[4]",$ck);
5959
# Dummy pages 1..6.
60-
print OUT chr(0) x (6 * 16384);
60+
$body = pack("x[16338]");
61+
for (my($page) = 1; $page < 7; $page++)
62+
{
63+
## FIL_PAGE_OFFSET
64+
$head = pack("Nx[18]", $page);
65+
$ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial);
66+
print OUT pack("N",$ck).$head.pack("x[16350]Nx[4]",$ck);
67+
}
6168
# Dictionary header page (page 7).
6269
## FIL_PAGE_OFFSET
6370
$head = pack("Nx[18]", 7);

mysql-test/suite/innodb/t/page_id_innochecksum.test

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,9 @@ let SEARCH_PATTERN=page id mismatch;
6161
--source include/search_pattern_in_file.inc
6262

6363
--remove_file $resultlog
64+
# prevent purge from crashing on page ID mismatch
65+
let $restart_parameters=--innodb-force-recovery=2;
6466
--source include/start_mysqld.inc
6567
drop table t1;
68+
let $restart_parameters=;
69+
--source include/restart_mysqld.inc

storage/innobase/dict/dict0crea.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ dict_build_index_def_step(
654654
index = node->index;
655655

656656
table = dict_table_open_on_name(
657-
node->table_name, true, DICT_ERR_IGNORE_DROP);
657+
node->table_name, true, DICT_ERR_IGNORE_TABLESPACE);
658658

659659
if (!table) {
660660
return DB_TABLE_NOT_FOUND;

storage/innobase/dict/dict0load.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2225,7 +2225,7 @@ dict_load_tablespace(
22252225
return;
22262226
}
22272227

2228-
if (ignore_err == DICT_ERR_IGNORE_DROP) {
2228+
if (ignore_err >= DICT_ERR_IGNORE_TABLESPACE) {
22292229
table->file_unreadable = true;
22302230
return;
22312231
}
@@ -2412,6 +2412,11 @@ static dict_table_t *dict_load_table_one(const span<const char> &name,
24122412
table->corrupted = true;
24132413
table->file_unreadable = true;
24142414
err = DB_CORRUPTION;
2415+
} else if (table->space->id
2416+
&& ignore_err == DICT_ERR_IGNORE_DROP) {
2417+
/* Do not bother to load data from .ibd files
2418+
only to delete the .ibd files. */
2419+
goto corrupted;
24152420
} else {
24162421
const page_id_t page_id(table->space->id, root);
24172422
mtr.start();

storage/innobase/fts/fts0fts.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,7 +1373,7 @@ fts_cache_add_doc(
13731373
static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename)
13741374
{
13751375
if (dict_table_t *table= dict_table_open_on_name(table_name, true,
1376-
DICT_ERR_IGNORE_DROP))
1376+
DICT_ERR_IGNORE_TABLESPACE))
13771377
{
13781378
table->release();
13791379
if (rename)
@@ -1505,7 +1505,7 @@ static dberr_t fts_lock_table(trx_t *trx, const char *table_name)
15051505
ut_ad(purge_sys.must_wait_FTS());
15061506

15071507
if (dict_table_t *table= dict_table_open_on_name(table_name, false,
1508-
DICT_ERR_IGNORE_DROP))
1508+
DICT_ERR_IGNORE_TABLESPACE))
15091509
{
15101510
dberr_t err= lock_table_for_trx(table, trx, LOCK_X);
15111511
/* Wait for purge threads to stop using the table. */

storage/innobase/ibuf/ibuf0ibuf.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,6 @@ static buf_block_t *ibuf_tree_root_get(mtr_t *mtr)
341341
page_id_t(IBUF_SPACE_ID, FSP_IBUF_TREE_ROOT_PAGE_NO),
342342
0, RW_SX_LATCH, mtr);
343343

344-
ut_ad(page_get_space_id(block->frame) == IBUF_SPACE_ID);
345-
ut_ad(page_get_page_no(block->frame) == FSP_IBUF_TREE_ROOT_PAGE_NO);
346344
ut_ad(ibuf.empty == page_is_empty(block->frame));
347345

348346
return block;

storage/innobase/include/btr0cur.ic

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22

33
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2018, 2020, MariaDB Corporation.
4+
Copyright (c) 2018, 2021, MariaDB Corporation.
55

66
This program is free software; you can redistribute it and/or modify it under
77
the terms of the GNU General Public License as published by the Free Software
@@ -109,10 +109,7 @@ btr_cur_position(
109109
buf_block_t* block, /*!< in: buffer block of rec */
110110
btr_cur_t* cursor) /*!< out: cursor */
111111
{
112-
ut_ad(page_align(rec) == block->frame);
113-
114112
page_cur_position(rec, block, btr_cur_get_page_cur(cursor));
115-
116113
cursor->index = index;
117114
}
118115

storage/innobase/include/dict0types.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ enum dict_err_ignore_t {
8282
incomplete index definitions. */
8383
/** ignore all errors above */
8484
DICT_ERR_IGNORE_ALL = 15,
85-
/** prepare to drop the table; do not attempt to load tablespace */
86-
DICT_ERR_IGNORE_DROP = 31
85+
/** prepare some DDL operation;
86+
do not attempt to load tablespace */
87+
DICT_ERR_IGNORE_TABLESPACE = 31,
88+
/** prepare to drop the table; do not attempt to load tablespace
89+
or the metadata */
90+
DICT_ERR_IGNORE_DROP = 63
8791
};
8892

8993
/** Quiescing states for flushing tables to disk. */

0 commit comments

Comments
 (0)