Commit 2e67b9f6 authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent bcb9ca41
...@@ -8,6 +8,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*"); ...@@ -8,6 +8,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*");
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Page for tablespace ");
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
FLUSH TABLES; FLUSH TABLES;
SET GLOBAL innodb_file_per_table = 1; SET GLOBAL innodb_file_per_table = 1;
CREATE TABLE t1 (c1 INT) ENGINE = InnoDB; CREATE TABLE t1 (c1 INT) ENGINE = InnoDB;
......
...@@ -583,10 +583,14 @@ DROP TABLE t1, parent; ...@@ -583,10 +583,14 @@ DROP TABLE t1, parent;
--echo #BUG#21514135 SCHEMA MISMATCH ERROR WHEN IMPORTING TABLESPACE AFTER --echo #BUG#21514135 SCHEMA MISMATCH ERROR WHEN IMPORTING TABLESPACE AFTER
--echo #DROPPING AN INDEX --echo #DROPPING AN INDEX
--echo # --echo #
--disable_query_log
call mtr.add_suppression("\\[Warning\\] InnoDB: Unknown index id .* on page");
--enable_query_log
let $source_db = source_db; let $source_db = source_db;
let $dest_db = dest_db; let $dest_db = dest_db;
--source include/default_charset.inc
SET NAMES utf8mb4; SET NAMES utf8mb4;
eval CREATE DATABASE $source_db; eval CREATE DATABASE $source_db;
......
...@@ -28,6 +28,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*"); ...@@ -28,6 +28,7 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .*");
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Page for tablespace ");
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=");
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
FLUSH TABLES; FLUSH TABLES;
let MYSQLD_DATADIR =`SELECT @@datadir`; let MYSQLD_DATADIR =`SELECT @@datadir`;
......
...@@ -3,6 +3,12 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau ...@@ -3,6 +3,12 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Page for tablespace ");
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x"); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
call mtr.add_suppression("InnoDB: Operating system error number");
call mtr.add_suppression("InnoDB: The error means");
call mtr.add_suppression("InnoDB: If you are installing InnoDB");
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`t1`");
FLUSH TABLES; FLUSH TABLES;
SET SESSION innodb_strict_mode=1; SET SESSION innodb_strict_mode=1;
CREATE TABLE t1 (c1 INT) ENGINE = Innodb CREATE TABLE t1 (c1 INT) ENGINE = Innodb
......
...@@ -19,6 +19,12 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau ...@@ -19,6 +19,12 @@ call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* becau
call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file"); call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file");
call mtr.add_suppression("InnoDB: Page for tablespace "); call mtr.add_suppression("InnoDB: Page for tablespace ");
call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x"); call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x");
call mtr.add_suppression("InnoDB: Unknown index id .* on page");
call mtr.add_suppression("InnoDB: Operating system error number");
call mtr.add_suppression("InnoDB: The error means");
call mtr.add_suppression("InnoDB: If you are installing InnoDB");
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`t1`");
FLUSH TABLES; FLUSH TABLES;
let MYSQLD_DATADIR =`SELECT @@datadir`; let MYSQLD_DATADIR =`SELECT @@datadir`;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2020, MariaDB Corporation. Copyright (c) 2015, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -1880,38 +1880,33 @@ dberr_t ...@@ -1880,38 +1880,33 @@ dberr_t
PageConverter::update_index_page( PageConverter::update_index_page(
buf_block_t* block) UNIV_NOTHROW buf_block_t* block) UNIV_NOTHROW
{ {
index_id_t id;
buf_frame_t* page = block->frame;
const page_id_t page_id(block->page.id()); const page_id_t page_id(block->page.id());
if (is_free(page_id.page_no())) { if (is_free(page_id.page_no())) {
return(DB_SUCCESS); return(DB_SUCCESS);
} else if ((id = btr_page_get_index_id(page)) != m_index->m_id) { }
buf_frame_t* page = block->frame;
const index_id_t id = btr_page_get_index_id(page);
row_index_t* index = find_index(id); if (id != m_index->m_id) {
row_index_t* index = find_index(id);
if (UNIV_UNLIKELY(!index)) { if (UNIV_UNLIKELY(!index)) {
ib::error() << "Page for tablespace " << m_space ib::warn() << "Unknown index id " << id
<< " is index page with id " << id << " on page " << page_id.page_no();
<< " but that index is not found from" return DB_SUCCESS;
<< " configuration file. Current index name "
<< m_index->m_name << " and id " << m_index->m_id;
m_index = 0;
return(DB_CORRUPTION);
} }
/* Update current index */
m_index = index; m_index = index;
} }
/* If the .cfg file is missing and there is an index mismatch /* If the .cfg file is missing and there is an index mismatch
then ignore the error. */ then ignore the error. */
if (m_cfg->m_missing && (m_index == 0 || m_index->m_srv_index == 0)) { if (m_cfg->m_missing && !m_index->m_srv_index) {
return(DB_SUCCESS); return(DB_SUCCESS);
} }
if (m_index && page_id.page_no() == m_index->m_page_no) { if (m_index && page_id.page_no() == m_index->m_page_no) {
byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE
+ page; + page;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment