summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-03-19 14:23:47 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-03-19 14:23:47 +0200
commit6960e9ed24dbdab587730cdceab1f29bcdd6d52a (patch)
tree9f0e495db2eb4a9c2608f5e52faab764c650b40e /storage
parent9fd692aecacfc944fd3a6a58f4cae5a49eeb1cf0 (diff)
downloadmariadb-git-6960e9ed24dbdab587730cdceab1f29bcdd6d52a.tar.gz
MDEV-21983: Crash on DROP/RENAME TABLE after DISCARD TABLESPACE
fil_delete_tablespace(): Remove the unused parameter drop_ahi, and add the parameter if_exists=false. We want to suppress error messages if we know that the tablespace has been discarded. dict_table_rename_in_cache(): Pass the new parameter to fil_delete_tablespace(), that is, do not complain about missing tablespace if the tablespace has been discarded. row_make_new_pathname(): Declare as static. row_drop_table_for_mysql(): Tolerate !table->data_dir_path when the tablespace has been discarded. row_rename_table_for_mysql(): Skip part of the RENAME TABLE when fil_space_get_first_path() returns NULL.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/dict/dict0dict.cc3
-rw-r--r--storage/innobase/fil/fil0fil.cc18
-rw-r--r--storage/innobase/include/fil0fil.h11
-rw-r--r--storage/innobase/include/row0merge.h14
-rw-r--r--storage/innobase/row/row0merge.cc1
-rw-r--r--storage/innobase/row/row0mysql.cc14
6 files changed, 21 insertions, 40 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index cf70047ab15..455d51af438 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1630,7 +1630,8 @@ dict_table_rename_in_cache(
return(DB_OUT_OF_MEMORY);
}
- fil_delete_tablespace(table->space);
+ fil_delete_tablespace(table->space,
+ dict_table_is_discarded(table));
/* Delete any temp file hanging around. */
if (os_file_status(filepath, &exists, &ftype)
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 64c2834a635..4192008ecf0 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -2861,14 +2861,9 @@ bool fil_table_accessible(const dict_table_t* table)
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
+@param[in] if_exists whether to ignore missing tablespace
@return DB_SUCCESS or error */
-dberr_t
-fil_delete_tablespace(
- ulint id
-#ifdef BTR_CUR_HASH_ADAPT
- , bool drop_ahi /*!< whether to drop the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
- )
+dberr_t fil_delete_tablespace(ulint id, bool if_exists)
{
char* path = 0;
fil_space_t* space = 0;
@@ -2879,10 +2874,11 @@ fil_delete_tablespace(
id, FIL_OPERATION_DELETE, &space, &path);
if (err != DB_SUCCESS) {
-
- ib::error() << "Cannot delete tablespace " << id
- << " because it is not found in the tablespace"
- " memory cache.";
+ if (!if_exists) {
+ ib::error() << "Cannot delete tablespace " << id
+ << " because it is not found"
+ " in the tablespace memory cache.";
+ }
return(err);
}
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 5484477d913..9c722944665 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -964,14 +964,9 @@ bool fil_table_accessible(const dict_table_t* table)
/** Delete a tablespace and associated .ibd file.
@param[in] id tablespace identifier
+@param[in] if_exists whether to ignore missing tablespace
@return DB_SUCCESS or error */
-dberr_t
-fil_delete_tablespace(
- ulint id
-#ifdef BTR_CUR_HASH_ADAPT
- , bool drop_ahi = false /*!< whether to drop the adaptive hash index */
-#endif /* BTR_CUR_HASH_ADAPT */
- );
+dberr_t fil_delete_tablespace(ulint id, bool if_exists= false);
/** Prepare to truncate an undo tablespace.
@param[in] space_id undo tablespace id
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index a9b275c890e..8e7ca5de046 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -203,18 +203,6 @@ row_merge_file_destroy_low(
int fd); /*!< in: merge file descriptor */
/*********************************************************************//**
-Provide a new pathname for a table that is being renamed if it belongs to
-a file-per-table tablespace. The caller is responsible for freeing the
-memory allocated for the return value.
-@return new pathname of tablespace file, or NULL if space = 0 */
-char*
-row_make_new_pathname(
-/*==================*/
- dict_table_t* table, /*!< in: table to be renamed */
- const char* new_name) /*!< in: new name */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
-/*********************************************************************//**
Rename the tables in the data dictionary. The data dictionary must
have been locked exclusively by the caller, because the transaction
will not be committed.
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index d218c166a1b..29f69317a18 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -4149,6 +4149,7 @@ Provide a new pathname for a table that is being renamed if it belongs to
a file-per-table tablespace. The caller is responsible for freeing the
memory allocated for the return value.
@return new pathname of tablespace file, or NULL if space = 0 */
+static
char*
row_make_new_pathname(
/*==================*/
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index a437c8d5ff1..9add75b3a67 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3725,10 +3725,12 @@ do_drop:
dict_table_t. Free this memory before returning. */
if (DICT_TF_HAS_DATA_DIR(table->flags)) {
dict_get_and_save_data_dir_path(table, true);
- ut_a(table->data_dir_path);
+ ut_ad(table->data_dir_path
+ || dict_table_is_discarded(table));
filepath = fil_make_filepath(
table->data_dir_path,
- table->name.m_name, IBD, true);
+ table->name.m_name, IBD,
+ table->data_dir_path != NULL);
} else {
filepath = fil_make_filepath(
NULL, table->name.m_name, IBD, false);
@@ -4304,11 +4306,9 @@ row_rename_table_for_mysql(
/* SYS_TABLESPACES and SYS_DATAFILES need to be updated if
the table is in a single-table tablespace. */
- if (err == DB_SUCCESS
- && dict_table_is_file_per_table(table)) {
- /* Make a new pathname to update SYS_DATAFILES. */
- char* new_path = row_make_new_pathname(table, new_name);
- char* old_path = fil_space_get_first_path(table->space);
+ if (err != DB_SUCCESS || !dict_table_is_file_per_table(table)) {
+ } else if (char* old_path = fil_space_get_first_path(table->space)) {
+ char* new_path = os_file_make_new_pathname(old_path, new_name);
/* If old path and new path are the same means tablename
has not changed and only the database name holding the table