diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index ee06ea9b9c099..d2ce12662fd2f 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -808,9 +808,8 @@ dict_acquire_mdl_shared(dict_table_t *table, if (trylock) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; db_len= dict_get_db_name_len(table->name.m_name); - dict_sys.unfreeze(); } else { @@ -871,9 +870,8 @@ dict_table_t *dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_sys.unlock(); if (table && thd) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table= dict_acquire_mdl_shared(table, thd, mdl, table_op); - dict_sys.unfreeze(); } return table; } @@ -3651,19 +3649,13 @@ dict_index_get_if_in_cache( /*=======================*/ index_id_t index_id) /*!< in: index id */ { - dict_index_t* index; - if (!dict_sys.is_initialised()) { return(NULL); } - dict_sys.freeze(SRW_LOCK_CALL); - - index = dict_index_get_if_in_cache_low(index_id); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; - dict_sys.unfreeze(); - - return(index); + return dict_index_get_if_in_cache_low(index_id); } /**********************************************************************//** @@ -3930,7 +3922,7 @@ dict_print_info_on_foreign_keys( dict_foreign_t* foreign; std::string str; - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; for (dict_foreign_set::iterator it = table->foreign_set.begin(); it != table->foreign_set.end(); @@ -3997,7 +3989,6 @@ dict_print_info_on_foreign_keys( } } - dict_sys.unfreeze(); return str; } @@ -4191,14 +4182,12 @@ void dict_set_merge_threshold_all_debug( uint merge_threshold_all) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; dict_set_merge_threshold_list_debug( &dict_sys.table_LRU, merge_threshold_all); dict_set_merge_threshold_list_debug( &dict_sys.table_non_LRU, merge_threshold_all); - - dict_sys.unfreeze(); } #endif /* UNIV_DEBUG */ diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index d9a9689205f00..4d2b317473c4e 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -3209,10 +3209,9 @@ dict_stats_save( dict_table_t* table_stats = dict_table_open_on_name( TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (table_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table_stats = dict_acquire_mdl_shared(table_stats, thd, &mdl_table); - dict_sys.unfreeze(); } if (!table_stats || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) { @@ -3226,10 +3225,9 @@ dict_stats_save( dict_table_t* index_stats = dict_table_open_on_name( INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (index_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; index_stats = dict_acquire_mdl_shared(index_stats, thd, &mdl_index); - dict_sys.unfreeze(); } if (!index_stats) { goto release_and_exit; @@ -3788,10 +3786,9 @@ dict_stats_fetch_from_ps( dict_table_t* table_stats = dict_table_open_on_name( TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (table_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table_stats = dict_acquire_mdl_shared(table_stats, thd, &mdl_table); - dict_sys.unfreeze(); } if (!table_stats || strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) { @@ -3805,10 +3802,9 @@ dict_stats_fetch_from_ps( dict_table_t* index_stats = dict_table_open_on_name( INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (index_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; index_stats = dict_acquire_mdl_shared(index_stats, thd, &mdl_index); - dict_sys.unfreeze(); } if (!index_stats) { goto release_and_exit; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c8ef77c3dbab0..e94474c418d44 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1367,19 +1367,17 @@ static void innodb_drop_database(handlerton*, char *path) DICT_ERR_IGNORE_NONE); if (table_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table_stats= dict_acquire_mdl_shared(table_stats, thd, &mdl_table); - dict_sys.unfreeze(); } index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (index_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; index_stats= dict_acquire_mdl_shared(index_stats, thd, &mdl_index); - dict_sys.unfreeze(); } trx_start_for_ddl(trx); @@ -13553,20 +13551,18 @@ int ha_innobase::delete_table(const char *name) DICT_ERR_IGNORE_NONE); if (table_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table_stats= dict_acquire_mdl_shared(table_stats, thd, &mdl_table); - dict_sys.unfreeze(); } index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (index_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; index_stats= dict_acquire_mdl_shared(index_stats, thd, &mdl_index); - dict_sys.unfreeze(); } const bool skip_wait{table->name.is_temporary()}; @@ -13805,10 +13801,9 @@ int ha_innobase::truncate() /* fk_truncate_illegal_if_parent() should have failed in Sql_cmd_truncate_table::handler_truncate() if foreign_key_checks=ON and child tables exist. */ - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; for (const auto foreign : m_prebuilt->table->referenced_set) ut_ad(foreign->foreign_table == m_prebuilt->table); - dict_sys.unfreeze(); } #endif @@ -13927,19 +13922,17 @@ int ha_innobase::truncate() DICT_ERR_IGNORE_NONE); if (table_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table_stats= dict_acquire_mdl_shared(table_stats, m_user_thd, &mdl_table); - dict_sys.unfreeze(); } index_stats= dict_table_open_on_name(INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (index_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; index_stats= dict_acquire_mdl_shared(index_stats, m_user_thd, &mdl_index); - dict_sys.unfreeze(); } if (table_stats && index_stats && @@ -14099,18 +14092,16 @@ ha_innobase::rename_table( table_stats = dict_table_open_on_name(TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (table_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table_stats = dict_acquire_mdl_shared( table_stats, thd, &mdl_table); - dict_sys.unfreeze(); } index_stats = dict_table_open_on_name(INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (index_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; index_stats = dict_acquire_mdl_shared( index_stats, thd, &mdl_index); - dict_sys.unfreeze(); } if (error == DB_SUCCESS && table_stats && index_stats @@ -15642,10 +15633,8 @@ REPLACE, not an update. uint ha_innobase::referenced_by_foreign_key() { - dict_sys.freeze(SRW_LOCK_CALL); - const bool empty= m_prebuilt->table->referenced_set.empty(); - dict_sys.unfreeze(); - return !empty; + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; + return !m_prebuilt->table->referenced_set.empty(); } /*******************************************************************//** diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c92d65f7f7c5d..54dbe0b0b0a8c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -11404,18 +11404,16 @@ ha_innobase::commit_inplace_alter_table( table_stats = dict_table_open_on_name( TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (table_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; table_stats = dict_acquire_mdl_shared( table_stats, m_user_thd, &mdl_table); - dict_sys.unfreeze(); } index_stats = dict_table_open_on_name( INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE); if (index_stats) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; index_stats = dict_acquire_mdl_shared( index_stats, m_user_thd, &mdl_index); - dict_sys.unfreeze(); } if (table_stats && index_stats diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 106e991c59ebf..cc950a20f6a44 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1570,6 +1570,28 @@ class dict_sys_t dberr_t create_or_check_sys_tables(); }; +/*********************************************************************//** +Freeze a dict_sys_t and automatically unfreeze it when the scope exits. */ +class Scope_freeze_dict_sys { + dict_sys_t &the_dict_sys; + +public: + explicit Scope_freeze_dict_sys(dict_sys_t &_the_dict_sys SRW_LOCK_ARGS2(const char *file, unsigned line)) noexcept + :the_dict_sys(_the_dict_sys) + { + the_dict_sys.freeze(SRW_LOCK_ARGS(file, line)); + } + + ~Scope_freeze_dict_sys() noexcept { + the_dict_sys.unfreeze(); + } + +private: + // copying/moving not allowed + Scope_freeze_dict_sys(const Scope_freeze_dict_sys &) = delete; + Scope_freeze_dict_sys &operator=(const Scope_freeze_dict_sys &) = delete; +}; + /** the data dictionary cache */ extern dict_sys_t dict_sys; diff --git a/storage/innobase/include/srw_lock.h b/storage/innobase/include/srw_lock.h index 10edc2ad0a0af..f2521082dbbbf 100644 --- a/storage/innobase/include/srw_lock.h +++ b/storage/innobase/include/srw_lock.h @@ -410,13 +410,17 @@ typedef ssux_lock_impl srw_spin_lock_low; #ifndef UNIV_PFS_RWLOCK # define SRW_LOCK_INIT(key) init() # define SRW_LOCK_ARGS(file, line) /* nothing */ +# define SRW_LOCK_ARGS2(file, line) /* nothing */ # define SRW_LOCK_CALL /* nothing */ +# define SRW_LOCK_CALL2 /* nothing */ typedef srw_lock_low srw_lock; typedef srw_spin_lock_low srw_spin_lock; #else # define SRW_LOCK_INIT(key) init(key) # define SRW_LOCK_ARGS(file, line) file, line +# define SRW_LOCK_ARGS2(file, line) , file, line # define SRW_LOCK_CALL __FILE__, __LINE__ +# define SRW_LOCK_CALL2 , __FILE__, __LINE__ /** Slim shared-update-exclusive lock with PERFORMANCE_SCHEMA instrumentation */ class ssux_lock diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 27eb62841a663..2a28bd1a72271 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -4121,7 +4121,7 @@ dberr_t lock_table_children(dict_table_t *table, trx_t *trx) if ((err= lock_table_for_trx(child.table, trx, LOCK_X)) != DB_SUCCESS) break; - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; for (table_mdl &child : children) { if (child.mdl) @@ -4130,7 +4130,6 @@ dberr_t lock_table_children(dict_table_t *table, trx_t *trx) mdl_context->release_lock(child.mdl); } } - dict_sys.unfreeze(); return err; } diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index b78a2c410af85..f3301d4071c0b 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -383,9 +383,8 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked) node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; node->table = dict_sys.acquire_temporary_table(table_id); - dict_sys.unfreeze(); } else { node->table = dict_sys.acquire_temporary_table(table_id); } diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 3493d624f1fbe..9b09ed6bf863a 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1210,9 +1210,8 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked) node->table = dict_table_open_on_id(table_id, dict_locked, DICT_TABLE_OP_NORMAL); } else if (!dict_locked) { - dict_sys.freeze(SRW_LOCK_CALL); + const Scope_freeze_dict_sys freeze_dict_sys{dict_sys SRW_LOCK_CALL2}; node->table = dict_sys.acquire_temporary_table(table_id); - dict_sys.unfreeze(); } else { node->table = dict_sys.acquire_temporary_table(table_id); }