summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-04-07 10:57:38 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-04-07 10:57:38 +0300
commit867617a97684cdf2c8df326d9a986c2cae779796 (patch)
tree3bedef66d55e986d543697c241eea40f9757bf5c
parent6b3e2ec10f91ec47a792965c248693e836e9dbae (diff)
downloadmariadb-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.test6
-rw-r--r--storage/innobase/dict/dict0load.cc10
-rw-r--r--storage/innobase/fil/fil0fil.cc59
-rw-r--r--storage/innobase/include/dict0types.h5
-rw-r--r--storage/innobase/include/fil0fil.h4
-rw-r--r--storage/innobase/row/row0mysql.cc4
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);