diff --git a/mysql-test/suite/innodb/r/bug-76142.result b/mysql-test/suite/innodb/r/bug-76142.result new file mode 100644 index 0000000..26e2930 --- /dev/null +++ b/mysql-test/suite/innodb/r/bug-76142.result @@ -0,0 +1,26 @@ +# +# Bug 76142: InnoDB tablespace import fails when importing table w/ different data directory +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB DATA DIRECTORY='MYSQL_TMP_DIR'; +INSERT INTO t2 VALUES (3); +FLUSH TABLE t2 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +INSERT INTO t2 VALUES (2); +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 IMPORT TABLESPACE; +INSERT INTO t1 VALUES (4); +SELECT * FROM t1; +a +3 +4 +SELECT * FROM t2; +a +1 +2 +DROP TABLE t1, t2; diff --git a/mysql-test/suite/innodb/r/default_row_format_compatibility.result b/mysql-test/suite/innodb/r/default_row_format_compatibility.result index 70c6b63..988d5f1 100644 --- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result +++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result @@ -40,7 +40,7 @@ SET GLOBAL innodb_default_row_format=Dynamic; CREATE TABLE tab(a INT); ALTER TABLE tab DISCARD TABLESPACE; ALTER TABLE tab IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x4 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1) DROP TABLE tab; SET GLOBAL innodb_default_row_format=Compact; SELECT @@innodb_default_row_format; diff --git a/mysql-test/suite/innodb/r/innodb-wl5522.result b/mysql-test/suite/innodb/r/innodb-wl5522.result index 1228dfc..dbd6065 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522.result @@ -113,7 +113,7 @@ ALTER TABLE t2 DISCARD TABLESPACE; # List after t2 DISCARD t2.frm ALTER TABLE t2 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x4 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1) ALTER TABLE t2 IMPORT TABLESPACE; ERROR HY000: Schema mismatch (Table has ROW_TYPE_DYNAMIC row format, .ibd file has ROW_TYPE_COMPACT row format.) DROP TABLE t2; @@ -593,7 +593,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x5 and the meta-data file has 0x0) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x0) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -605,7 +605,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x5 and the meta-data file has 0x0) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x0) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -779,7 +779,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x5 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x1) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -791,7 +791,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x5 and the meta-data file has 0x1) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x21 and the meta-data file has 0x1) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -968,7 +968,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x5 and the meta-data file has 0x21) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x21) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; @@ -980,7 +980,7 @@ SELECT * FROM t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x5 and the meta-data file has 0x21) +ERROR HY000: Schema mismatch (Table flags don't match, server table has 0x0 and the meta-data file has 0x21) unlink: t1.ibd unlink: t1.cfg DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/bug-76142.test b/mysql-test/suite/innodb/t/bug-76142.test new file mode 100644 index 0000000..1fb92fe --- /dev/null +++ b/mysql-test/suite/innodb/t/bug-76142.test @@ -0,0 +1,42 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug 76142: InnoDB tablespace import fails when importing table w/ different data directory +--echo # + +--let $MYSQLD_DATADIR = `SELECT @@datadir` +--let $DB = `SELECT DATABASE()` + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB DATA DIRECTORY='$MYSQL_TMP_DIR'; +INSERT INTO t2 VALUES (3); + +FLUSH TABLE t2 FOR EXPORT; +--copy_file $MYSQL_TMP_DIR/$DB/t2.cfg $MYSQLD_DATADIR/$DB/temp.cfg +--copy_file $MYSQL_TMP_DIR/$DB/t2.ibd $MYSQLD_DATADIR/$DB/temp.ibd +UNLOCK TABLES; + +ALTER TABLE t2 DISCARD TABLESPACE; + +FLUSH TABLE t1 FOR EXPORT; +--copy_file $MYSQLD_DATADIR/$DB/t1.cfg $MYSQL_TMP_DIR/$DB/t2.cfg +--copy_file $MYSQLD_DATADIR/$DB/t1.ibd $MYSQL_TMP_DIR/$DB/t2.ibd +UNLOCK TABLES; + +ALTER TABLE t2 IMPORT TABLESPACE; +INSERT INTO t2 VALUES (2); + +ALTER TABLE t1 DISCARD TABLESPACE; +--move_file $MYSQLD_DATADIR/$DB/temp.cfg $MYSQLD_DATADIR/$DB/t1.cfg +--move_file $MYSQLD_DATADIR/$DB/temp.ibd $MYSQLD_DATADIR/$DB/t1.ibd + +ALTER TABLE t1 IMPORT TABLESPACE; +INSERT INTO t1 VALUES (4); + +SELECT * FROM t1; +SELECT * FROM t2; + +DROP TABLE t1, t2; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index fba267e..b7eedea 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -808,14 +808,20 @@ retry: << ib::hex(space->flags) << ")!"; } - if (space->flags != flags) { + /* Validate the flags but do not compare the data directory + flag, in case this tablespace was relocated. */ + const unsigned relevant_space_flags + = space->flags & ~FSP_FLAGS_MASK_DATA_DIR; + const unsigned relevant_flags + = flags & ~FSP_FLAGS_MASK_DATA_DIR; + if (UNIV_UNLIKELY(relevant_space_flags != relevant_flags)) { ib::fatal() << "Table flags are " - << ib::hex(space->flags) << " in the data" - " dictionary but the flags in file " - << node->name << " are " << ib::hex(flags) - << "!"; + << ib::hex(relevant_space_flags) << " in the " + "data dictionary but the flags in file " + << node->name << " are " + << ib::hex(relevant_flags) << "!"; } { diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 8894441..614a583 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -594,8 +594,8 @@ xdes_get_descriptor_with_space_hdr( || (srv_startup_is_before_trx_rollback_phase && fspace->id <= srv_undo_tablespaces)))); ut_ad(size == fspace->size_in_header); - ut_ad(flags == fspace->flags); - + ut_ad((flags & ~FSP_FLAGS_MASK_DATA_DIR) + == (fspace->flags & ~FSP_FLAGS_MASK_DATA_DIR)); if ((offset >= size) || (offset >= limit)) { return(NULL); } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 9dbb2f3..de746e8 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1309,12 +1309,15 @@ row_import::match_schema( THD* thd) UNIV_NOTHROW { /* Do some simple checks. */ + const unsigned relevant_flags = m_flags & ~DICT_TF_MASK_DATA_DIR; + const unsigned relevant_table_flags + = m_table->flags & ~DICT_TF_MASK_DATA_DIR; - if (m_flags != m_table->flags) { + if (relevant_flags != relevant_table_flags) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Table flags don't match, server table has 0x%lx" - " and the meta-data file has 0x%lx", - (ulong) m_table->n_cols, (ulong) m_flags); + "Table flags don't match, server table has 0x%x " + "and the meta-data file has 0x%x", + relevant_table_flags, relevant_flags); return(DB_ERROR); } else if (m_table->n_cols != m_n_cols) {