diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-08 17:34:34 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-08 17:34:34 +0200 |
commit | e572c745dc04ac7659a40849abce62f39a0b09d4 (patch) | |
tree | 4c2e87d76235a80bbfa297f02b18ecde95f7dc2b /storage/innobase/dict | |
parent | f4519fb772b2c2c0a6dcb0b93cb147e5dc1627b2 (diff) | |
download | mariadb-git-e572c745dc04ac7659a40849abce62f39a0b09d4.tar.gz |
MDEV-29504/MDEV-29849 TRUNCATE breaks FOREIGN KEY locking
ha_innobase::referenced_by_foreign_key(): Protect the check with
dict_sys.freeze(), to prevent races with TRUNCATE TABLE.
The test innodb.instant_alter_crash has been adjusted for this
additional locking.
dict_table_is_referenced_by_foreign_key(): Removed (merged to
the only caller).
create_table_info_t::create_table(): Ignore missing indexes for
FOREIGN KEY constraints if foreign_key_checks=0.
create_table_info_t::create_table_update_dict(): Rewritten as
a static function. Do not return any error.
ha_innobase::create(): When trx!=nullptr and we are operating
on a persistent table, do not rollback, commit, or release the
data dictionary latch.
ha_innobase::truncate(): Protect the entire critical section
with an exclusive dict_sys.latch, so that
ha_innobase::referenced_by_foreign_key() on referenced tables
will return a consistent result. In case of a failure,
invoke dict_load_foreigns() to restore also any FOREIGN KEY
constraints.
ha_innobase::free_foreign_key_create_info(): Define inline.
lock_release(): Disregard innodb_evict_tables_on_commit_debug=ON
when dict_sys.locked() holds. It would hold when fts_load_stopword()
is invoked by create_table_info_t::create_table_update_dict().
dict_sys_t::locked(): Return whether the current thread is holding
the exclusive dict_sys.latch.
dict_sys_t::frozen_not_locked(): Return whether any thread is
holding a shared dict_sys.latch.
In the test main.mysql_upgrade, the InnoDB persistent statistics
will no longer be recalculated in ha_innobase::open() as part of
CHECK TABLE ... FOR UPGRADE. They were deleted earlier in the test.
Tested by: Matthias Leich
Diffstat (limited to 'storage/innobase/dict')
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 22 |
1 files changed, 5 insertions, 17 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 43ccf8c4d09..362b949e10f 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -685,8 +685,7 @@ dict_acquire_mdl_shared(dict_table_t *table, } else { - ut_ad(dict_sys.frozen()); - ut_ad(!dict_sys.locked()); + ut_ad(dict_sys.frozen_not_locked()); db_len= dict_get_db_name_len(table->name.m_name); } @@ -1003,7 +1002,7 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) latch_ex_wait_start.store(0, std::memory_order_relaxed); ut_ad(!latch_readers); ut_ad(!latch_ex); - ut_d(latch_ex= true); + ut_d(latch_ex= pthread_self()); return; } @@ -1021,15 +1020,15 @@ void dict_sys_t::lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line)) latch.wr_lock(SRW_LOCK_ARGS(file, line)); ut_ad(!latch_readers); ut_ad(!latch_ex); - ut_d(latch_ex= true); + ut_d(latch_ex= pthread_self()); } #ifdef UNIV_PFS_RWLOCK ATTRIBUTE_NOINLINE void dict_sys_t::unlock() { - ut_ad(latch_ex); + ut_ad(latch_ex == pthread_self()); ut_ad(!latch_readers); - ut_d(latch_ex= false); + ut_d(latch_ex= 0); latch.wr_unlock(); } @@ -2749,17 +2748,6 @@ dict_index_build_internal_fts( } /*====================== FOREIGN KEY PROCESSING ========================*/ -/*********************************************************************//** -Checks if a table is referenced by foreign keys. -@return TRUE if table is referenced by a foreign key */ -ibool -dict_table_is_referenced_by_foreign_key( -/*====================================*/ - const dict_table_t* table) /*!< in: InnoDB table */ -{ - return(!table->referenced_set.empty()); -} - /**********************************************************************//** Removes a foreign constraint struct from the dictionary cache. */ void |