mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-29144 ER_TABLE_SCHEMA_MISMATCH or crash on DISCARD/IMPORT
mysql_discard_or_import_tablespace(): On successful ALTER TABLE...DISCARD TABLESPACE, evict the table handle from the table definition cache, so that ha_innobase::close() will be invoked, like InnoDB expects to be the case. This will avoid an assertion failure ut_a(table->get_ref_count() == 0) during IMPORT TABLESPACE. ha_innobase::open(): Do not issue any ER_TABLESPACE_DISCARDED warning. Member functions for DML will do that. ha_innobase::truncate(), ha_innobase::check_if_supported_inplace_alter(): Issue ER_TABLESPACE_DISCARDED warnings, to compensate for the removal of the warning in ha_innobase::open(). row_quiesce_write_indexes(): Only write information about committed indexes. The ALTER TABLE t NOWAIT ADD INDEX(c) in the nondeterministic test case will most of the time fail due to a metadata lock (MDL) timeout and leave behind an uncommitted index. Reviewed by: Sergei Golubchik
This commit is contained in:
parent
8f3631d009
commit
782b2a7500
7 changed files with 110 additions and 7 deletions
|
@ -44,7 +44,6 @@ ALTER TABLE t1 DISCARD TABLESPACE;
|
|||
restore: t1 .ibd and .cfg files
|
||||
ALTER TABLE t1 DISCARD TABLESPACE;
|
||||
Warnings:
|
||||
Warning 1814 Tablespace has been discarded for table `t1`
|
||||
Warning 1812 Tablespace is missing for table 'test/t1'
|
||||
restore: t1 .ibd and .cfg files
|
||||
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||
|
|
26
mysql-test/suite/innodb/r/import_tablespace_race.result
Normal file
26
mysql-test/suite/innodb/r/import_tablespace_race.result
Normal file
|
@ -0,0 +1,26 @@
|
|||
#
|
||||
# MDEV-29144 ER_TABLE_SCHEMA_MISMATCH or crash on DISCARD/IMPORT
|
||||
#
|
||||
CREATE TABLE t (pk int PRIMARY KEY, c varchar(1024))
|
||||
ENGINE=InnoDB CHARSET latin1;
|
||||
INSERT INTO t SELECT seq, 'x' FROM seq_1_to_100;
|
||||
connect con1,localhost,root,,test;
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE a INT DEFAULT 0;
|
||||
REPEAT
|
||||
SET a= a+1;
|
||||
UPDATE t SET c = 'xx' WHERE pk = a;
|
||||
UNTIL a = 100
|
||||
END REPEAT;
|
||||
END
|
||||
$
|
||||
connection default;
|
||||
ALTER TABLE t NOWAIT ADD INDEX (c);
|
||||
connection con1;
|
||||
connection default;
|
||||
FLUSH TABLE t FOR EXPORT;
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t;
|
||||
ALTER TABLE t DISCARD TABLESPACE;
|
||||
ALTER TABLE t IMPORT TABLESPACE;
|
||||
DROP TABLE t;
|
54
mysql-test/suite/innodb/t/import_tablespace_race.test
Normal file
54
mysql-test/suite/innodb/t/import_tablespace_race.test
Normal file
|
@ -0,0 +1,54 @@
|
|||
--source include/have_innodb.inc
|
||||
--source include/have_sequence.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-29144 ER_TABLE_SCHEMA_MISMATCH or crash on DISCARD/IMPORT
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t (pk int PRIMARY KEY, c varchar(1024))
|
||||
ENGINE=InnoDB CHARSET latin1;
|
||||
INSERT INTO t SELECT seq, 'x' FROM seq_1_to_100;
|
||||
|
||||
--connect (con1,localhost,root,,test)
|
||||
--delimiter $
|
||||
--send
|
||||
BEGIN NOT ATOMIC
|
||||
DECLARE a INT DEFAULT 0;
|
||||
REPEAT
|
||||
SET a= a+1;
|
||||
UPDATE t SET c = 'xx' WHERE pk = a;
|
||||
UNTIL a = 100
|
||||
END REPEAT;
|
||||
END
|
||||
$
|
||||
--delimiter ;
|
||||
|
||||
--connection default
|
||||
--error 0,ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE t NOWAIT ADD INDEX (c);
|
||||
|
||||
--connection con1
|
||||
--reap
|
||||
|
||||
--connection default
|
||||
|
||||
--let $datadir= `select @@datadir`
|
||||
|
||||
FLUSH TABLE t FOR EXPORT;
|
||||
--let $create= query_get_value(SHOW CREATE TABLE t, Create Table, 1)
|
||||
--copy_file $datadir/test/t.cfg $MYSQL_TMP_DIR/t.cfg
|
||||
--copy_file $datadir/test/t.ibd $MYSQL_TMP_DIR/t.ibd
|
||||
UNLOCK TABLES;
|
||||
|
||||
DROP TABLE t;
|
||||
--disable_query_log
|
||||
eval $create;
|
||||
--enable_query_log
|
||||
|
||||
ALTER TABLE t DISCARD TABLESPACE;
|
||||
--move_file $MYSQL_TMP_DIR/t.cfg $datadir/test/t.cfg
|
||||
--move_file $MYSQL_TMP_DIR/t.ibd $datadir/test/t.ibd
|
||||
ALTER TABLE t IMPORT TABLESPACE;
|
||||
|
||||
# Cleanup
|
||||
DROP TABLE t;
|
|
@ -6075,6 +6075,10 @@ int mysql_discard_or_import_tablespace(THD *thd,
|
|||
if (unlikely(error))
|
||||
goto err;
|
||||
|
||||
if (discard)
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, table_list->table->s->db.str,
|
||||
table_list->table->s->table_name.str, true);
|
||||
|
||||
/*
|
||||
The 0 in the call below means 'not in a transaction', which means
|
||||
immediate invalidation; that is probably what we wish here
|
||||
|
|
|
@ -6268,11 +6268,6 @@ no_such_table:
|
|||
MONITOR_INC(MONITOR_TABLE_OPEN);
|
||||
|
||||
if ((ib_table->flags2 & DICT_TF2_DISCARDED)) {
|
||||
|
||||
ib_senderrf(thd,
|
||||
IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED,
|
||||
table->s->table_name.str);
|
||||
|
||||
/* Allow an open because a proper DISCARD should have set
|
||||
all the flags and index root page numbers to FIL_NULL that
|
||||
should prevent any DML from running but it should allow DDL
|
||||
|
@ -13631,6 +13626,12 @@ int ha_innobase::truncate()
|
|||
if (ib_table->is_temporary()) {
|
||||
info.options|= HA_LEX_CREATE_TMP_TABLE;
|
||||
} else {
|
||||
if (!ib_table->space) {
|
||||
ib_senderrf(m_user_thd,
|
||||
IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED,
|
||||
table->s->table_name.str);
|
||||
}
|
||||
|
||||
dict_get_and_save_data_dir_path(ib_table, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -1013,6 +1013,12 @@ ha_innobase::check_if_supported_inplace_alter(
|
|||
|
||||
update_thd();
|
||||
|
||||
if (!m_prebuilt->table->space) {
|
||||
ib_senderrf(m_user_thd, IB_LOG_LEVEL_WARN,
|
||||
ER_TABLESPACE_DISCARDED,
|
||||
table->s->table_name.str);
|
||||
}
|
||||
|
||||
if (ha_alter_info->handler_flags
|
||||
& ~(INNOBASE_INPLACE_IGNORE
|
||||
| INNOBASE_ALTER_INSTANT
|
||||
|
|
|
@ -106,11 +106,17 @@ row_quiesce_write_indexes(
|
|||
FILE* file, /*!< in: file to write to */
|
||||
THD* thd) /*!< in/out: session */
|
||||
{
|
||||
ulint n_indexes = 0;
|
||||
for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
|
||||
index; index = UT_LIST_GET_NEXT(indexes, index)) {
|
||||
n_indexes += index->is_committed();
|
||||
}
|
||||
|
||||
{
|
||||
byte row[sizeof(ib_uint32_t)];
|
||||
|
||||
/* Write the number of indexes in the table. */
|
||||
mach_write_to_4(row, UT_LIST_GET_LEN(table->indexes));
|
||||
mach_write_to_4(row, n_indexes);
|
||||
|
||||
DBUG_EXECUTE_IF("ib_export_io_write_failure_11",
|
||||
close(fileno(file)););
|
||||
|
@ -132,6 +138,12 @@ row_quiesce_write_indexes(
|
|||
index != 0 && err == DB_SUCCESS;
|
||||
index = UT_LIST_GET_NEXT(indexes, index)) {
|
||||
|
||||
if (!index->is_committed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ut_ad(n_indexes); ut_d(n_indexes--);
|
||||
|
||||
byte* ptr;
|
||||
byte row[sizeof(index_id_t)
|
||||
+ sizeof(ib_uint32_t) * 8];
|
||||
|
@ -202,6 +214,7 @@ row_quiesce_write_indexes(
|
|||
err = row_quiesce_write_index_fields(index, file, thd);
|
||||
}
|
||||
|
||||
ut_ad(!n_indexes);
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue