diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-04-07 10:57:38 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-04-07 10:57:38 +0300 |
commit | 867617a97684cdf2c8df326d9a986c2cae779796 (patch) | |
tree | 3bedef66d55e986d543697c241eea40f9757bf5c | |
parent | 6b3e2ec10f91ec47a792965c248693e836e9dbae (diff) | |
download | mariadb-git-867617a97684cdf2c8df326d9a986c2cae779796.tar.gz |
MDEV-18309: InnoDB reports bogus errors about missing #sql-*.ibd on startup
This is a follow-up to MDEV-18733. As part of that fix, we made
dict_check_sys_tables() skip tables that would be dropped by
row_mysql_drop_garbage_tables().
DICT_ERR_IGNORE_DROP: A new mode where the file should not be attempted
to be opened.
dict_load_tablespace(): Do not try to load the tablespace if
DICT_ERR_IGNORE_DROP has been specified.
row_mysql_drop_garbage_tables(): Pass the DICT_ERR_IGNORE_DROP mode.
fil_space_for_table_exists_in_mem(): Remove a parameter.
The only caller that passed print_error_if_does_not_exist=true
was row_drop_single_table_tablespace().
-rw-r--r-- | mysql-test/suite/innodb/t/drop_table_background.test | 6 | ||||
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 10 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 59 | ||||
-rw-r--r-- | storage/innobase/include/dict0types.h | 5 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 4 |
6 files changed, 21 insertions, 67 deletions
diff --git a/mysql-test/suite/innodb/t/drop_table_background.test b/mysql-test/suite/innodb/t/drop_table_background.test index 8d82bea9675..20101dada84 100644 --- a/mysql-test/suite/innodb/t/drop_table_background.test +++ b/mysql-test/suite/innodb/t/drop_table_background.test @@ -3,6 +3,8 @@ # Embedded server does not support restarting --source include/not_embedded.inc +let $MYSQLD_DATADIR=`select @@datadir`; + CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT, KEY(c1), KEY(c2), KEY(c2,c1), KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1), @@ -32,7 +34,9 @@ CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t; --error ER_NO_SUCH_TABLE SELECT * from target; DROP TABLE t; ---source include/restart_mysqld.inc +--source include/shutdown_mysqld.inc +--remove_files_wildcard $MYSQLD_DATADIR/test #sql-*.ibd +--source include/start_mysqld.inc CREATE TABLE t (a INT) ENGINE=InnoDB; DROP TABLE t; --error ER_BAD_TABLE_ERROR diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 304a536505c..fc399faaea3 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1449,8 +1449,7 @@ next: /* Now that we have the proper name for this tablespace, look to see if it is already in the tablespace cache. */ if (fil_space_for_table_exists_in_mem( - space_id, table_name.m_name, - false, NULL, flags)) { + space_id, table_name.m_name, NULL, flags)) { /* Recovery can open a datafile that does not match SYS_DATAFILES. If they don't match, update SYS_DATAFILES. */ @@ -2845,7 +2844,12 @@ dict_load_tablespace( /* The tablespace may already be open. */ if (fil_space_for_table_exists_in_mem( - table->space, space_name, false, heap, table->flags)) { + table->space, space_name, heap, table->flags)) { + return; + } + + if (ignore_err == DICT_ERR_IGNORE_DROP) { + table->file_unreadable = true; return; } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index be594ec83c1..3c9546b0304 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -4540,9 +4540,6 @@ memory cache. Note that if we have not done a crash recovery at the database startup, there may be many tablespaces which are not yet in the memory cache. @param[in] id Tablespace ID @param[in] name Tablespace name used in fil_space_create(). -@param[in] print_error_if_does_not_exist - Print detailed error information to the -error log if a matching tablespace is not found from memory. @param[in] heap Heap memory @param[in] table_flags table flags @return true if a matching tablespace exists in the memory cache */ @@ -4550,11 +4547,9 @@ bool fil_space_for_table_exists_in_mem( ulint id, const char* name, - bool print_error_if_does_not_exist, mem_heap_t* heap, ulint table_flags) { - fil_space_t* fnamespace; fil_space_t* space; const ulint expected_flags = dict_tf_to_fsp_flags(table_flags); @@ -4568,58 +4563,10 @@ fil_space_for_table_exists_in_mem( /* Look if there is a space with the same name; the name is the directory path from the datadir to the file */ - fnamespace = fil_space_get_by_name(name); - bool valid = space && !((space->flags ^ expected_flags) - & ~FSP_FLAGS_MEM_MASK); + const bool valid = space + && !((space->flags ^ expected_flags) & ~FSP_FLAGS_MEM_MASK) + && space == fil_space_get_by_name(name); - if (!space) { - } else if (!valid || space == fnamespace) { - /* Found with the same file name, or got a flag mismatch. */ - goto func_exit; - } - - if (!print_error_if_does_not_exist) { - valid = false; - goto func_exit; - } - - if (space == NULL) { - if (fnamespace == NULL) { - if (print_error_if_does_not_exist) { - fil_report_missing_tablespace(name, id); - } - } else { - ib::error() << "Table " << name << " in InnoDB data" - " dictionary has tablespace id " << id - << ", but a tablespace with that id does not" - " exist. There is a tablespace of name " - << fnamespace->name << " and id " - << fnamespace->id << ", though. Have you" - " deleted or moved .ibd files?"; - } -error_exit: - ib::info() << TROUBLESHOOT_DATADICT_MSG; - valid = false; - goto func_exit; - } - - if (0 != strcmp(space->name, name)) { - - ib::error() << "Table " << name << " in InnoDB data dictionary" - " has tablespace id " << id << ", but the tablespace" - " with that id has name " << space->name << "." - " Have you deleted or moved .ibd files?"; - - if (fnamespace != NULL) { - ib::error() << "There is a tablespace with the right" - " name: " << fnamespace->name << ", but its id" - " is " << fnamespace->id << "."; - } - - goto error_exit; - } - -func_exit: if (valid) { /* Adjust the flags that are in FSP_FLAGS_MEM_MASK. FSP_SPACE_FLAGS will not be written back here. */ diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index 27b4cc0e694..ae47a621cf0 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -70,7 +70,10 @@ enum dict_err_ignore_t { Silently load a missing tablespace, and do not load incomplete index definitions. */ - DICT_ERR_IGNORE_ALL = 0xFFFF /*!< ignore all errors */ + /** ignore all errors above */ + DICT_ERR_IGNORE_ALL = 15, + /** prepare to drop the table; do not attempt to load tablespace */ + DICT_ERR_IGNORE_DROP = 31 }; /** Quiescing states for flushing tables to disk. */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 72a66b497a2..1096b990146 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1162,9 +1162,6 @@ memory cache. Note that if we have not done a crash recovery at the database startup, there may be many tablespaces which are not yet in the memory cache. @param[in] id Tablespace ID @param[in] name Tablespace name used in fil_space_create(). -@param[in] print_error_if_does_not_exist - Print detailed error information to the -error log if a matching tablespace is not found from memory. @param[in] heap Heap memory @param[in] table_flags table flags @return true if a matching tablespace exists in the memory cache */ @@ -1172,7 +1169,6 @@ bool fil_space_for_table_exists_in_mem( ulint id, const char* name, - bool print_error_if_does_not_exist, mem_heap_t* heap, ulint table_flags); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 29fc79a7d3e..76024bbe170 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2675,7 +2675,7 @@ row_mysql_drop_garbage_tables() btr_pcur_commit_specify_mtr(&pcur, &mtr); if (dict_load_table(table_name, true, - DICT_ERR_IGNORE_ALL)) { + DICT_ERR_IGNORE_DROP)) { row_drop_table_for_mysql( table_name, trx, SQLCOM_DROP_TABLE); @@ -3231,7 +3231,7 @@ row_drop_single_table_tablespace( /* If the tablespace is not in the cache, just delete the file. */ if (!fil_space_for_table_exists_in_mem( - space_id, tablename, true, NULL, table_flags)) { + space_id, tablename, NULL, table_flags)) { /* Force a delete of any discarded or temporary files. */ fil_delete_file(filepath); |