summaryrefslogtreecommitdiff
path: root/storage/innobase/dict/dict0crea.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-05-18 12:53:40 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-05-18 12:53:40 +0300
commitc366845a0b5c08285c958cf1500b3b7906ecf8d4 (patch)
treeb4314fa09e7277ec356d667a2a5cfd3293f9e919 /storage/innobase/dict/dict0crea.cc
parentf09d33f521b50bb8a0a27764c9732f0dda2aeefb (diff)
downloadmariadb-git-c366845a0b5c08285c958cf1500b3b7906ecf8d4.tar.gz
MDEV-25691: Simplify handlerton::drop_database for InnoDB
The implementation of handlerton::drop_database in InnoDB is unnecessarily complex. The minimal implementation should check that no conflicting locks or references exist on the tables, delete all table metadata in a single transaction, and finally delete the tablespaces. Note: DROP DATABASE will delete each individual table that the SQL layer knows about, one table per transaction. The handlerton::drop_database is basically a final cleanup step for removing any garbage that could have been left behind in InnoDB due to some bug, or not having atomic DDL in the past. hash_node_t: Remove. Use the proper data type name in pointers. dict_drop_index_tree(): Do not take the table as a parameter. Instead, return the tablespace ID if the tablespace should be dropped (we are dropping a clustered index tree). fil_delete_tablespace(), fil_system_t::detach(): Return a single detached file handle. Multi-file tablespaces cannot be deleted via this interface. ha_innobase::delete_table(): Remove a work-around for non-atomic DDL and do not try to drop tables with similar-looking name. innodb_drop_database(): Complete rewrite. innobase_drop_database(), dict_get_first_table_name_in_db(), row_drop_database_for_mysql(), drop_all_foreign_keys_in_db(): Remove. row_purge_remove_clust_if_poss_low(), row_undo_ins_remove_clust_rec(): If the tablespace is to be deleted, try to evict the table definition from the cache. Failing that, set dict_table_t::space to nullptr. lock_release_on_rollback(): On the rollback of CREATE TABLE, release all locks that the transaction had on the table, to avoid heap-use-after-free.
Diffstat (limited to 'storage/innobase/dict/dict0crea.cc')
-rw-r--r--storage/innobase/dict/dict0crea.cc23
1 files changed, 10 insertions, 13 deletions
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 5d24edad598..0b1c39e145e 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -826,10 +826,10 @@ dict_create_index_tree_in_mem(
/** Drop the index tree associated with a row in SYS_INDEXES table.
@param[in,out] pcur persistent cursor on rec
@param[in,out] trx dictionary transaction
-@param[in,out] table table that the record belongs to
-@param[in,out] mtr mini-transaction */
-void dict_drop_index_tree(btr_pcur_t *pcur, trx_t *trx, dict_table_t *table,
- mtr_t *mtr)
+@param[in,out] mtr mini-transaction
+@return tablespace ID to drop (if this is the clustered index)
+@retval 0 if no tablespace is to be dropped */
+uint32_t dict_drop_index_tree(btr_pcur_t *pcur, trx_t *trx, mtr_t *mtr)
{
rec_t *rec= btr_pcur_get_rec(pcur);
@@ -846,7 +846,7 @@ void dict_drop_index_tree(btr_pcur_t *pcur, trx_t *trx, dict_table_t *table,
{
rec_corrupted:
ib::error() << "Corrupted SYS_INDEXES record";
- return;
+ return 0;
}
if (rec_get_1byte_offs_flag(rec))
@@ -875,14 +875,9 @@ rec_corrupted:
ut_ad(root_page_no == FIL_NULL || space_id <= SRV_SPACE_ID_UPPER_BOUND);
if (space_id && (type & DICT_CLUSTERED))
- {
- if (table && table->space_id == space_id)
- table->space= nullptr;
- else
- ut_ad(!table);
- fil_delete_tablespace(space_id, true);
- }
- else if (root_page_no == FIL_NULL)
+ return space_id;
+
+ if (root_page_no == FIL_NULL)
/* The tree has already been freed */;
else if (fil_space_t*s= fil_space_t::get(space_id))
{
@@ -898,6 +893,8 @@ rec_corrupted:
}
s->release();
}
+
+ return 0;
}
/*********************************************************************//**