diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns.result b/mysql-test/suite/innodb/r/innodb-virtual-columns.result index f91c4615af0..b08e01b346e 100644 --- a/mysql-test/suite/innodb/r/innodb-virtual-columns.result +++ b/mysql-test/suite/innodb/r/innodb-virtual-columns.result @@ -388,3 +388,20 @@ CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +# +# MDEV-40274 Server aborts while reloading the table after +# DISCARD TABLESPACE +# +call mtr.add_suppression("InnoDB: DISCARD TABLESPACE of table `test`\\.`t1` failed"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); +call mtr.add_suppression("Table `test`\\.`t1` is corrupted"); +CREATE TABLE t1(c1 INT) ENGINE=InnoDB; +SET STATEMENT debug_dbug='+d,row_ins_sec_index_entry_timeout' FOR +ALTER TABLE t1 DISCARD TABLESPACE; +ERROR HY000: Got error 168 "Unknown (generic) error from engine" from storage engine InnoDB +ALTER TABLE t1 ADD COLUMN cg16 INT AS(c1) VIRTUAL; +ERROR 42000: Can't open table +FLUSH TABLES; +SELECT * FROM t1; +ERROR HY000: Table `test`.`t1` is corrupted. Please drop the table and recreate. +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-virtual-columns.test b/mysql-test/suite/innodb/t/innodb-virtual-columns.test index 6bb9ddc8dc4..5a9b73608aa 100644 --- a/mysql-test/suite/innodb/t/innodb-virtual-columns.test +++ b/mysql-test/suite/innodb/t/innodb-virtual-columns.test @@ -363,3 +363,23 @@ SET GLOBAL innodb_max_purge_lag_wait=0; CHECK TABLE t1 EXTENDED; DROP TABLE t1; + +--echo # +--echo # MDEV-40274 Server aborts while reloading the table after +--echo # DISCARD TABLESPACE +--echo # + +call mtr.add_suppression("InnoDB: DISCARD TABLESPACE of table `test`\\.`t1` failed"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); +call mtr.add_suppression("Table `test`\\.`t1` is corrupted"); + +CREATE TABLE t1(c1 INT) ENGINE=InnoDB; +--error ER_GET_ERRNO +SET STATEMENT debug_dbug='+d,row_ins_sec_index_entry_timeout' FOR +ALTER TABLE t1 DISCARD TABLESPACE; +--error ER_CHECK_NO_SUCH_TABLE +ALTER TABLE t1 ADD COLUMN cg16 INT AS(c1) VIRTUAL; +FLUSH TABLES; +--error ER_TABLE_CORRUPT +SELECT * FROM t1; +DROP TABLE t1; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 4b76391e484..1edd5d71ea0 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1038,7 +1038,8 @@ dict_table_open_on_name( if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && !table->is_readable() && table->corrupted) { - ulint algo= table->space->get_compression_algo(); + const ulint algo= table->space + ? table->space->get_compression_algo() : ULINT_UNDEFINED; if (algo <= PAGE_ALGORITHM_LAST && !fil_comp_algo_loaded(algo)) my_printf_error(ER_PROVIDER_NOT_LOADED, "Table %`.*s.%`s is compressed with %s," diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 6e66c8f5ecd..6dfb58639e9 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2460,6 +2460,19 @@ rollback: table->space= nullptr; table->flags2|= DICT_TF2_DISCARDED; err= row_discard_tablespace(trx, table); + if (UNIV_UNLIKELY(err != DB_SUCCESS)) + { + /* In case of error, table cannot be loaded from the data + dictionary any longer. Flag the table as corrupted, so that no + operation other than DROP TABLE will be attempted on it. */ + table->corrupted= true; + ib::error() << "DISCARD TABLESPACE of table " << table->name + << " failed: " << ut_strerr(err) + << "; the data dictionary is now inconsistent. Please" + " DROP TABLE " << table->name + << " and restore it from a backup."; + } + DBUG_EXECUTE_IF("ib_discard_before_commit_crash", log_buffer_flush_to_disk(); DBUG_SUICIDE();); /* FTS_ tables may be deleted */