summaryrefslogtreecommitdiff
path: root/storage/innobase/include/dict0dict.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/dict0dict.h')
-rw-r--r--storage/innobase/include/dict0dict.h73
1 files changed, 45 insertions, 28 deletions
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 17263fdd48a..024a8652a12 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1312,9 +1312,6 @@ dict_index_calc_min_rec_len(
const dict_index_t* index) /*!< in: index */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-#define dict_mutex_enter_for_mysql() mutex_enter(&dict_sys.mutex)
-#define dict_mutex_exit_for_mysql() mutex_exit(&dict_sys.mutex)
-
/********************************************************************//**
Checks if the database name in two table names is the same.
@return TRUE if same db name */
@@ -1378,13 +1375,14 @@ constraint */
/* Buffers for storing detailed information about the latest foreign key
and unique key errors */
extern FILE* dict_foreign_err_file;
-extern ib_mutex_t dict_foreign_err_mutex; /* mutex protecting the
- foreign key error messages */
+extern mysql_mutex_t dict_foreign_err_mutex;
/** InnoDB data dictionary cache */
class dict_sys_t
{
-private:
+ /** The my_hrtime_coarse().val of the oldest mutex_lock_wait() start, or 0 */
+ std::atomic<ulonglong> mutex_wait_start;
+
/** @brief the data dictionary rw-latch protecting dict_sys
Table create, drop, etc. reserve this in X-mode (along with
@@ -1399,14 +1397,11 @@ private:
/** whether latch is being held in exclusive mode (by any thread) */
bool latch_ex;
#endif
+ /** Mutex protecting dict_sys. Whenever latch is acquired
+ exclusively, also the mutex will be acquired.
+ FIXME: merge the mutex and the latch, once MDEV-23484 has been fixed */
+ mysql_mutex_t mutex;
public:
- DictSysMutex mutex; /*!< mutex protecting the data
- dictionary; protects also the
- disk-based dictionary system tables;
- this mutex serializes CREATE TABLE
- and DROP TABLE, as well as reading
- the dictionary data for a table from
- system tables */
hash_table_t table_hash; /*!< hash table of the tables, based
on name */
/** hash table of persistent table IDs */
@@ -1437,6 +1432,9 @@ private:
/** The synchronization interval of row_id */
static constexpr size_t ROW_ID_WRITE_MARGIN= 256;
public:
+ /** Diagnostic message for exceeding the mutex_lock_wait() timeout */
+ static const char fatal_msg[];
+
/** @return A new value for GEN_CLUST_INDEX(DB_ROW_ID) */
inline row_id_t get_new_row_id();
@@ -1461,7 +1459,7 @@ public:
(should only happen during the rollback of CREATE...SELECT) */
dict_table_t* get_temporary_table(table_id_t id)
{
- ut_ad(mutex_own(&mutex));
+ mysql_mutex_assert_owner(&mutex);
dict_table_t* table;
ulint fold = ut_fold_ull(id);
HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table,
@@ -1480,7 +1478,7 @@ public:
@retval NULL if not cached */
dict_table_t* get_table(table_id_t id)
{
- ut_ad(mutex_own(&mutex));
+ mysql_mutex_assert_owner(&mutex);
dict_table_t* table;
ulint fold = ut_fold_ull(id);
HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*,
@@ -1515,7 +1513,7 @@ public:
{
ut_ad(table);
ut_ad(table->can_be_evicted == in_lru);
- ut_ad(mutex_own(&mutex));
+ mysql_mutex_assert_owner(&mutex);
for (const dict_table_t* t = UT_LIST_GET_FIRST(in_lru
? table_LRU : table_non_LRU);
t; t = UT_LIST_GET_NEXT(table_LRU, t))
@@ -1546,25 +1544,44 @@ public:
/** Acquire a reference to a cached table. */
inline void acquire(dict_table_t* table);
-#ifdef UNIV_DEBUG
- /** Assert that the data dictionary is locked */
- void assert_locked() { ut_ad(mutex_own(&mutex)); }
+ /** Assert that the mutex is locked */
+ void assert_locked() const { mysql_mutex_assert_owner(&mutex); }
+ /** Assert that the mutex is not locked */
+ void assert_not_locked() const { mysql_mutex_assert_not_owner(&mutex); }
+#ifdef SAFE_MUTEX
+ bool mutex_is_locked() const { return mysql_mutex_is_owner(&mutex); }
#endif
+private:
+ /** Acquire the mutex */
+ ATTRIBUTE_NOINLINE void mutex_lock_wait();
+public:
+ /** @return the my_hrtime_coarse().val of the oldest mutex_lock_wait() start,
+ assuming that requests are served on a FIFO basis */
+ ulonglong oldest_wait() const
+ { return mutex_wait_start.load(std::memory_order_relaxed); }
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ /** Acquire the mutex */
+ ATTRIBUTE_NOINLINE void mutex_lock();
+ /** Release the mutex */
+ ATTRIBUTE_NOINLINE void mutex_unlock();
+#else
+ /** Acquire the mutex */
+ void mutex_lock() { if (mysql_mutex_trylock(&mutex)) mutex_lock_wait(); }
+
+ /** Release the mutex */
+ void mutex_unlock() { mysql_mutex_unlock(&mutex); }
+#endif
+
/** Lock the data dictionary cache. */
- void lock(const char* file, unsigned line)
- {
- latch.wr_lock(SRW_LOCK_ARGS(file, line));
- ut_ad(!latch_ex);
- ut_d(latch_ex= true);
- mutex_enter_loc(&mutex, file, line);
- }
+ void lock(SRW_LOCK_ARGS(const char *file, unsigned line));
/** Unlock the data dictionary cache. */
void unlock()
{
ut_ad(latch_ex);
ut_d(latch_ex= false);
- mutex_exit(&mutex);
+ mutex_unlock();
latch.wr_unlock();
}
@@ -1595,7 +1612,7 @@ public:
extern dict_sys_t dict_sys;
#define dict_table_prevent_eviction(table) dict_sys.prevent_eviction(table)
-#define dict_sys_lock() dict_sys.lock(__FILE__, __LINE__)
+#define dict_sys_lock() dict_sys.lock(SRW_LOCK_CALL)
#define dict_sys_unlock() dict_sys.unlock()
/* Auxiliary structs for checking a table definition @{ */