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().
This commit is contained in:
parent
6b3e2ec10f
commit
867617a976
@ -3,6 +3,8 @@
|
|||||||
# Embedded server does not support restarting
|
# Embedded server does not support restarting
|
||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
|
let $MYSQLD_DATADIR=`select @@datadir`;
|
||||||
|
|
||||||
CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT,
|
CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT,
|
||||||
KEY(c1), KEY(c2), KEY(c2,c1),
|
KEY(c1), KEY(c2), KEY(c2,c1),
|
||||||
KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,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
|
--error ER_NO_SUCH_TABLE
|
||||||
SELECT * from target;
|
SELECT * from target;
|
||||||
DROP TABLE t;
|
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;
|
CREATE TABLE t (a INT) ENGINE=InnoDB;
|
||||||
DROP TABLE t;
|
DROP TABLE t;
|
||||||
--error ER_BAD_TABLE_ERROR
|
--error ER_BAD_TABLE_ERROR
|
||||||
|
@ -1449,8 +1449,7 @@ next:
|
|||||||
/* Now that we have the proper name for this tablespace,
|
/* Now that we have the proper name for this tablespace,
|
||||||
look to see if it is already in the tablespace cache. */
|
look to see if it is already in the tablespace cache. */
|
||||||
if (fil_space_for_table_exists_in_mem(
|
if (fil_space_for_table_exists_in_mem(
|
||||||
space_id, table_name.m_name,
|
space_id, table_name.m_name, NULL, flags)) {
|
||||||
false, NULL, flags)) {
|
|
||||||
/* Recovery can open a datafile that does not
|
/* Recovery can open a datafile that does not
|
||||||
match SYS_DATAFILES. If they don't match, update
|
match SYS_DATAFILES. If they don't match, update
|
||||||
SYS_DATAFILES. */
|
SYS_DATAFILES. */
|
||||||
@ -2845,7 +2844,12 @@ dict_load_tablespace(
|
|||||||
|
|
||||||
/* The tablespace may already be open. */
|
/* The tablespace may already be open. */
|
||||||
if (fil_space_for_table_exists_in_mem(
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
startup, there may be many tablespaces which are not yet in the memory cache.
|
||||||
@param[in] id Tablespace ID
|
@param[in] id Tablespace ID
|
||||||
@param[in] name Tablespace name used in fil_space_create().
|
@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] heap Heap memory
|
||||||
@param[in] table_flags table flags
|
@param[in] table_flags table flags
|
||||||
@return true if a matching tablespace exists in the memory cache */
|
@return true if a matching tablespace exists in the memory cache */
|
||||||
@ -4550,11 +4547,9 @@ bool
|
|||||||
fil_space_for_table_exists_in_mem(
|
fil_space_for_table_exists_in_mem(
|
||||||
ulint id,
|
ulint id,
|
||||||
const char* name,
|
const char* name,
|
||||||
bool print_error_if_does_not_exist,
|
|
||||||
mem_heap_t* heap,
|
mem_heap_t* heap,
|
||||||
ulint table_flags)
|
ulint table_flags)
|
||||||
{
|
{
|
||||||
fil_space_t* fnamespace;
|
|
||||||
fil_space_t* space;
|
fil_space_t* space;
|
||||||
|
|
||||||
const ulint expected_flags = dict_tf_to_fsp_flags(table_flags);
|
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
|
/* Look if there is a space with the same name; the name is the
|
||||||
directory path from the datadir to the file */
|
directory path from the datadir to the file */
|
||||||
|
|
||||||
fnamespace = fil_space_get_by_name(name);
|
const bool valid = space
|
||||||
bool valid = space && !((space->flags ^ expected_flags)
|
&& !((space->flags ^ expected_flags) & ~FSP_FLAGS_MEM_MASK)
|
||||||
& ~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) {
|
if (valid) {
|
||||||
/* Adjust the flags that are in FSP_FLAGS_MEM_MASK.
|
/* Adjust the flags that are in FSP_FLAGS_MEM_MASK.
|
||||||
FSP_SPACE_FLAGS will not be written back here. */
|
FSP_SPACE_FLAGS will not be written back here. */
|
||||||
|
@ -70,7 +70,10 @@ enum dict_err_ignore_t {
|
|||||||
Silently load a missing
|
Silently load a missing
|
||||||
tablespace, and do not load
|
tablespace, and do not load
|
||||||
incomplete index definitions. */
|
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. */
|
/** Quiescing states for flushing tables to disk. */
|
||||||
|
@ -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.
|
startup, there may be many tablespaces which are not yet in the memory cache.
|
||||||
@param[in] id Tablespace ID
|
@param[in] id Tablespace ID
|
||||||
@param[in] name Tablespace name used in fil_space_create().
|
@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] heap Heap memory
|
||||||
@param[in] table_flags table flags
|
@param[in] table_flags table flags
|
||||||
@return true if a matching tablespace exists in the memory cache */
|
@return true if a matching tablespace exists in the memory cache */
|
||||||
@ -1172,7 +1169,6 @@ bool
|
|||||||
fil_space_for_table_exists_in_mem(
|
fil_space_for_table_exists_in_mem(
|
||||||
ulint id,
|
ulint id,
|
||||||
const char* name,
|
const char* name,
|
||||||
bool print_error_if_does_not_exist,
|
|
||||||
mem_heap_t* heap,
|
mem_heap_t* heap,
|
||||||
ulint table_flags);
|
ulint table_flags);
|
||||||
|
|
||||||
|
@ -2675,7 +2675,7 @@ row_mysql_drop_garbage_tables()
|
|||||||
btr_pcur_commit_specify_mtr(&pcur, &mtr);
|
btr_pcur_commit_specify_mtr(&pcur, &mtr);
|
||||||
|
|
||||||
if (dict_load_table(table_name, true,
|
if (dict_load_table(table_name, true,
|
||||||
DICT_ERR_IGNORE_ALL)) {
|
DICT_ERR_IGNORE_DROP)) {
|
||||||
row_drop_table_for_mysql(
|
row_drop_table_for_mysql(
|
||||||
table_name, trx,
|
table_name, trx,
|
||||||
SQLCOM_DROP_TABLE);
|
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 the tablespace is not in the cache, just delete the file. */
|
||||||
if (!fil_space_for_table_exists_in_mem(
|
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. */
|
/* Force a delete of any discarded or temporary files. */
|
||||||
fil_delete_file(filepath);
|
fil_delete_file(filepath);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user