Skip to content

Commit 2e67b9f

Browse files
committed
MDEV-25265: ALTER TABLE...IMPORT TABLESPACE fails after DROP INDEX
A side effect of the MDEV-24589 bug fix is that if FLUSH TABLE...FOR EXPORT is initiated before the history of an earlier DROP INDEX operation has been purged, then the data file will contain allocated pages that belonged to the dropped indexes. These pages would never be freed after a subsequent IMPORT TABLESPACE. We will work around this regression by making IMPORT TABLESPACE tolerate pages that refer to an unknown index.
1 parent bcb9ca4 commit 2e67b9f

File tree

6 files changed

+30
-17
lines changed

6 files changed

+30
-17
lines changed

mysql-test/suite/innodb/r/innodb-wl5522-debug.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*");
88
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
99
call mtr.add_suppression("InnoDB: Page for tablespace ");
1010
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
11+
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
1112
FLUSH TABLES;
1213
SET GLOBAL innodb_file_per_table = 1;
1314
CREATE TABLE t1 (c1 INT) ENGINE = InnoDB;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,10 +583,14 @@ DROP TABLE t1, parent;
583583
--echo #BUG#21514135 SCHEMA MISMATCH ERROR WHEN IMPORTING TABLESPACE AFTER
584584
--echo #DROPPING AN INDEX
585585
--echo #
586+
587+
--disable_query_log
588+
call mtr.add_suppression("\\[Warning\\] InnoDB: Unknown index id .* on page");
589+
--enable_query_log
590+
586591
let $source_db = source_db;
587592
let $dest_db = dest_db;
588593

589-
--source include/default_charset.inc
590594
SET NAMES utf8mb4;
591595

592596
eval CREATE DATABASE $source_db;

mysql-test/suite/innodb/t/innodb-wl5522-debug.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*");
2828
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
2929
call mtr.add_suppression("InnoDB: Page for tablespace ");
3030
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
31+
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
3132
FLUSH TABLES;
3233

3334
let MYSQLD_DATADIR =`SELECT @@datadir`;

mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau
33
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
44
call mtr.add_suppression("InnoDB: Page for tablespace ");
55
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
6+
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
7+
call mtr.add_suppression("InnoDB: Operating system error number");
8+
call mtr.add_suppression("InnoDB: The error means");
9+
call mtr.add_suppression("InnoDB: If you are installing InnoDB");
10+
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
11+
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`t1`");
612
FLUSH TABLES;
713
SET SESSION innodb_strict_mode=1;
814
CREATE TABLE t1 (c1 INT) ENGINE = Innodb

mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau
1919
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
2020
call mtr.add_suppression("InnoDB: Page for tablespace ");
2121
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
22+
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
23+
call mtr.add_suppression("InnoDB: Operating system error number");
24+
call mtr.add_suppression("InnoDB: The error means");
25+
call mtr.add_suppression("InnoDB: If you are installing InnoDB");
26+
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
27+
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`t1`");
2228
FLUSH TABLES;
2329

2430
let MYSQLD_DATADIR =`SELECT @@datadir`;

storage/innobase/row/row0import.cc

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22
33
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2015, 2020, MariaDB Corporation.
4+
Copyright (c) 2015, 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
@@ -1880,38 +1880,33 @@ dberr_t
18801880
PageConverter::update_index_page(
18811881
buf_block_t* block) UNIV_NOTHROW
18821882
{
1883-
index_id_tid;
1884-
buf_frame_t* page = block->frame;
18851883
const page_id_t page_id(block->page.id());
18861884

18871885
if (is_free(page_id.page_no())) {
18881886
return(DB_SUCCESS);
1889-
} else if ((id = btr_page_get_index_id(page)) != m_index->m_id) {
1887+
}
1888+
1889+
buf_frame_t* page = block->frame;
1890+
const index_id_t id = btr_page_get_index_id(page);
18901891

1891-
row_index_t* index = find_index(id);
1892+
if (id != m_index->m_id) {
1893+
row_index_t* index = find_index(id);
18921894

18931895
if (UNIV_UNLIKELY(!index)) {
1894-
ib::error() << "Page for tablespace " << m_space
1895-
<< " is index page with id " << id
1896-
<< " but that index is not found from"
1897-
<< " configuration file. Current index name "
1898-
<< m_index->m_name << " and id " << m_index->m_id;
1899-
m_index = 0;
1900-
return(DB_CORRUPTION);
1896+
ib::warn() << "Unknown index id " << id
1897+
<< " on page " << page_id.page_no();
1898+
return DB_SUCCESS;
19011899
}
19021900

1903-
/* Update current index */
19041901
m_index = index;
19051902
}
19061903

19071904
/* If the .cfg file is missing and there is an index mismatch
19081905
then ignore the error. */
1909-
if (m_cfg->m_missing && (m_index == 0 || m_index->m_srv_index == 0)) {
1906+
if (m_cfg->m_missing && !m_index->m_srv_index) {
19101907
return(DB_SUCCESS);
19111908
}
19121909

1913-
1914-
19151910
if (m_index && page_id.page_no() == m_index->m_page_no) {
19161911
byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE
19171912
+ page;

0 commit comments

Comments
 (0)