diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-05-18 12:53:40 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-05-18 12:53:40 +0300 |
commit | c366845a0b5c08285c958cf1500b3b7906ecf8d4 (patch) | |
tree | b4314fa09e7277ec356d667a2a5cfd3293f9e919 /storage/innobase/dict/dict0crea.cc | |
parent | f09d33f521b50bb8a0a27764c9732f0dda2aeefb (diff) | |
download | mariadb-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.cc | 23 |
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; } /*********************************************************************//** |