summaryrefslogtreecommitdiff
path: root/storage/innobase/include
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-12-04 19:02:58 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-12-15 17:56:18 +0200
commitff5d306e296350e7489dd3decb01bad18d135411 (patch)
tree64e8673307ede8bf633e94947ed84e3dcaaa5b05 /storage/innobase/include
parentdb006a9a43b6e68c4b92d2762043fa76b313623c (diff)
downloadmariadb-git-ff5d306e296350e7489dd3decb01bad18d135411.tar.gz
MDEV-21452: Replace ib_mutex_t with mysql_mutex_t
SHOW ENGINE INNODB MUTEX functionality is completely removed, as are the InnoDB latching order checks. We will enforce innodb_fatal_semaphore_wait_threshold only for dict_sys.mutex and lock_sys.mutex. dict_sys_t::mutex_lock(): A single entry point for dict_sys.mutex. lock_sys_t::mutex_lock(): A single entry point for lock_sys.mutex. FIXME: srv_sys should be removed altogether; it is duplicating tpool functionality. fil_crypt_threads_init(): To prevent SAFE_MUTEX warnings, we must not hold fil_system.mutex. fil_close_all_files(): To prevent SAFE_MUTEX warnings for fil_space_destroy_crypt_data(), we must not hold fil_system.mutex while invoking fil_space_free_low() on a detached tablespace.
Diffstat (limited to 'storage/innobase/include')
-rw-r--r--storage/innobase/include/buf0types.h6
-rw-r--r--storage/innobase/include/dict0dict.h73
-rw-r--r--storage/innobase/include/dict0dict.ic8
-rw-r--r--storage/innobase/include/dict0priv.ic4
-rw-r--r--storage/innobase/include/dict0stats.ic4
-rw-r--r--storage/innobase/include/dict0stats_bg.h6
-rw-r--r--storage/innobase/include/dict0types.h6
-rw-r--r--storage/innobase/include/fil0fil.h24
-rw-r--r--storage/innobase/include/fts0fts.h8
-rw-r--r--storage/innobase/include/gis0rtree.ic6
-rw-r--r--storage/innobase/include/gis0type.h6
-rw-r--r--storage/innobase/include/hash0hash.h1
-rw-r--r--storage/innobase/include/ib0mutex.h610
-rw-r--r--storage/innobase/include/lock0lock.h40
-rw-r--r--storage/innobase/include/lock0priv.h4
-rw-r--r--storage/innobase/include/lock0priv.ic4
-rw-r--r--storage/innobase/include/log0log.ic12
-rw-r--r--storage/innobase/include/log0recv.h3
-rw-r--r--storage/innobase/include/mem0mem.ic2
-rw-r--r--storage/innobase/include/mtr0types.h13
-rw-r--r--storage/innobase/include/os0thread.h5
-rw-r--r--storage/innobase/include/page0types.h1
-rw-r--r--storage/innobase/include/page0zip.ic10
-rw-r--r--storage/innobase/include/read0types.h27
-rw-r--r--storage/innobase/include/row0mysql.h15
-rw-r--r--storage/innobase/include/srv0mon.h5
-rw-r--r--storage/innobase/include/srv0srv.h39
-rw-r--r--storage/innobase/include/sync0debug.h78
-rw-r--r--storage/innobase/include/sync0policy.h296
-rw-r--r--storage/innobase/include/sync0sync.h96
-rw-r--r--storage/innobase/include/sync0types.h967
-rw-r--r--storage/innobase/include/trx0purge.h2
-rw-r--r--storage/innobase/include/trx0rseg.h7
-rw-r--r--storage/innobase/include/trx0sys.h65
-rw-r--r--storage/innobase/include/trx0types.h13
-rw-r--r--storage/innobase/include/univ.i57
-rw-r--r--storage/innobase/include/ut0mutex.h174
-rw-r--r--storage/innobase/include/ut0new.h3
-rw-r--r--storage/innobase/include/ut0wqueue.h1
39 files changed, 278 insertions, 2423 deletions
diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h
index 7460c07a7d9..4fb93e75515 100644
--- a/storage/innobase/include/buf0types.h
+++ b/storage/innobase/include/buf0types.h
@@ -24,9 +24,7 @@ The database buffer pool global types for the directory
Created 11/17/1995 Heikki Tuuri
*******************************************************/
-#ifndef buf0types_h
-#define buf0types_h
-
+#pragma once
#include "univ.i"
/** Buffer page (uncompressed or compressed) */
@@ -228,5 +226,3 @@ public:
};
#endif /* !UNIV_INNOCHECKSUM */
-
-#endif /* buf0types.h */
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 @{ */
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index f97c65d5bfc..a494eefdc32 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1139,12 +1139,10 @@ dict_table_is_file_per_table(
}
/** Acquire the table handle. */
-inline
-void
-dict_table_t::acquire()
+inline void dict_table_t::acquire()
{
- ut_ad(mutex_own(&dict_sys.mutex));
- n_ref_count++;
+ dict_sys.assert_locked();
+ n_ref_count++;
}
/** Release the table handle.
diff --git a/storage/innobase/include/dict0priv.ic b/storage/innobase/include/dict0priv.ic
index 2fcadc055e1..36d0ba66524 100644
--- a/storage/innobase/include/dict0priv.ic
+++ b/storage/innobase/include/dict0priv.ic
@@ -39,7 +39,7 @@ dict_table_get_low(
dict_table_t* table;
ut_ad(table_name);
- ut_ad(mutex_own(&dict_sys.mutex));
+ dict_sys.assert_locked();
table = dict_table_check_if_in_cache_low(table_name);
@@ -79,7 +79,7 @@ dict_table_check_if_in_cache_low(
("table: '%s'", table_name));
ut_ad(table_name);
- ut_ad(mutex_own(&dict_sys.mutex));
+ dict_sys.assert_locked();
/* Look for the table name in the hash table */
table_fold = ut_fold_string(table_name);
diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic
index 4972efe8961..cfc3c0e7e21 100644
--- a/storage/innobase/include/dict0stats.ic
+++ b/storage/innobase/include/dict0stats.ic
@@ -148,7 +148,7 @@ dict_stats_init(
/*============*/
dict_table_t* table) /*!< in/out: table */
{
- ut_ad(!mutex_own(&dict_sys.mutex));
+ dict_sys.assert_not_locked();
if (table->stat_initialized) {
return;
@@ -174,7 +174,7 @@ dict_stats_deinit(
/*==============*/
dict_table_t* table) /*!< in/out: table */
{
- ut_ad(mutex_own(&dict_sys.mutex));
+ dict_sys.assert_locked();
ut_a(table->get_ref_count() == 0);
diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h
index b210a2ec357..5abbdf7fd25 100644
--- a/storage/innobase/include/dict0stats_bg.h
+++ b/storage/innobase/include/dict0stats_bg.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -31,7 +31,7 @@ Created Apr 26, 2012 Vasil Dimov
#include "os0thread.h"
#ifdef HAVE_PSI_INTERFACE
-extern mysql_pfs_key_t dict_stats_recalc_pool_mutex_key;
+extern mysql_pfs_key_t recalc_pool_mutex_key;
#endif /* HAVE_PSI_INTERFACE */
#ifdef UNIV_DEBUG
@@ -67,7 +67,7 @@ dict_stats_stop_bg(
dict_table_t* table) /*!< in/out: table */
{
ut_ad(!srv_read_only_mode);
- ut_ad(mutex_own(&dict_sys.mutex));
+ dict_sys.assert_locked();
if (!(table->stats_bg_flag & BG_STAT_IN_PROGRESS)) {
return(true);
diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h
index d0da45ab218..6db0f3ba65b 100644
--- a/storage/innobase/include/dict0types.h
+++ b/storage/innobase/include/dict0types.h
@@ -27,7 +27,7 @@ Created 1/8/1996 Heikki Tuuri
#ifndef dict0types_h
#define dict0types_h
-#include <ut0mutex.h>
+#include "univ.i"
#include <rem0types.h>
struct dict_col_t;
@@ -90,10 +90,6 @@ enum ib_quiesce_t {
QUIESCE_COMPLETE /*!< All done */
};
-#ifndef UNIV_INNOCHECKSUM
-typedef ib_mutex_t DictSysMutex;
-#endif /* !UNIV_INNOCHECKSUM */
-
/** Prefix for tmp tables, adopted from sql/table.h */
#define TEMP_FILE_PREFIX "#sql"
#define TEMP_FILE_PREFIX_LENGTH 4
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index d9f36479a44..a342e0e24bf 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1415,7 +1415,8 @@ public:
std::vector<pfs_os_file_t> detach(fil_space_t *space,
bool detach_handle= false);
- ib_mutex_t mutex; /*!< The mutex protecting the cache */
+ /** the mutex protecting most data fields, and some fields of fil_space_t */
+ mysql_mutex_t mutex;
fil_space_t* sys_space; /*!< The innodb_system tablespace */
fil_space_t* temp_space; /*!< The innodb_temporary tablespace */
/** Map of fil_space_t::id to fil_space_t* */
@@ -1467,14 +1468,18 @@ extern fil_system_t fil_system;
inline void fil_space_t::reacquire()
{
ut_d(uint32_t n=) n_pending.fetch_add(1, std::memory_order_relaxed);
- ut_d(if (mutex_own(&fil_system.mutex)) return);
+#ifdef SAFE_MUTEX
+ if (mysql_mutex_is_owner(&fil_system.mutex)) return;
ut_ad(n & PENDING);
ut_ad(UT_LIST_GET_FIRST(chain)->is_open());
+#endif /* SAFE_MUTEX */
}
inline bool fil_space_t::acquire_if_not_stopped(bool have_mutex)
{
- ut_ad(mutex_own(&fil_system.mutex) == have_mutex);
+#ifdef SAFE_MUTEX
+ ut_ad(mysql_mutex_is_owner(&fil_system.mutex) == have_mutex);
+#endif
const uint32_t n= acquire_low();
if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
return true;
@@ -1484,7 +1489,7 @@ inline bool fil_space_t::acquire_if_not_stopped(bool have_mutex)
/** Note that operations on the tablespace must stop or can resume */
inline void fil_space_t::set_stopping(bool stopping)
{
- ut_ad(mutex_own(&fil_system.mutex));
+ mysql_mutex_assert_owner(&fil_system.mutex);
ut_d(auto n=) n_pending.fetch_xor(STOPPING, std::memory_order_relaxed);
ut_ad(!(n & STOPPING) == stopping);
}
@@ -1492,7 +1497,7 @@ inline void fil_space_t::set_stopping(bool stopping)
/** Flush pending writes from the file system cache to the file. */
template<bool have_reference> inline void fil_space_t::flush()
{
- ut_ad(!mutex_own(&fil_system.mutex));
+ mysql_mutex_assert_not_owner(&fil_system.mutex);
ut_ad(!have_reference || (pending() & PENDING));
ut_ad(purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT);
if (srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)
@@ -1514,9 +1519,9 @@ inline uint32_t fil_space_t::get_size()
{
if (!size)
{
- mutex_enter(&fil_system.mutex);
+ mysql_mutex_lock(&fil_system.mutex);
read_page0();
- mutex_exit(&fil_system.mutex);
+ mysql_mutex_unlock(&fil_system.mutex);
}
return size;
}
@@ -1789,11 +1794,6 @@ char*
fil_path_to_space_name(
const char* filename);
-/** Acquire the fil_system mutex. */
-#define fil_system_enter() mutex_enter(&fil_system.mutex)
-/** Release the fil_system mutex. */
-#define fil_system_exit() mutex_exit(&fil_system.mutex)
-
/*******************************************************************//**
Returns the table space by a given id, NULL if not found. */
fil_space_t*
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 77649aa55ab..6c97c9ed868 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -377,12 +377,8 @@ extern ulong fts_min_token_size;
need a sync to free some memory */
extern bool fts_need_sync;
-#define fts_que_graph_free(graph) \
-do { \
- mutex_enter(&dict_sys.mutex); \
- que_graph_free(graph); \
- mutex_exit(&dict_sys.mutex); \
-} while (0)
+/** Free a query graph */
+void fts_que_graph_free(que_t *graph);
/******************************************************************//**
Create a FTS cache. */
diff --git a/storage/innobase/include/gis0rtree.ic b/storage/innobase/include/gis0rtree.ic
index 82747bdc95a..cb47c12da80 100644
--- a/storage/innobase/include/gis0rtree.ic
+++ b/storage/innobase/include/gis0rtree.ic
@@ -175,12 +175,12 @@ rtr_get_parent_node(
return(NULL);
}
- mutex_enter(&btr_cur->rtr_info->rtr_path_mutex);
+ mysql_mutex_lock(&btr_cur->rtr_info->rtr_path_mutex);
num = btr_cur->rtr_info->parent_path->size();
if (!num) {
- mutex_exit(&btr_cur->rtr_info->rtr_path_mutex);
+ mysql_mutex_unlock(&btr_cur->rtr_info->rtr_path_mutex);
return(NULL);
}
@@ -203,7 +203,7 @@ rtr_get_parent_node(
}
}
- mutex_exit(&btr_cur->rtr_info->rtr_path_mutex);
+ mysql_mutex_unlock(&btr_cur->rtr_info->rtr_path_mutex);
return(found_node);
}
diff --git a/storage/innobase/include/gis0type.h b/storage/innobase/include/gis0type.h
index 55944bfcce3..4fccfdb6c26 100644
--- a/storage/innobase/include/gis0type.h
+++ b/storage/innobase/include/gis0type.h
@@ -72,7 +72,7 @@ typedef struct matched_rec {
buf_block_t block; /*!< the shadow buffer block */
ulint used; /*!< memory used */
rtr_rec_vector* matched_recs; /*!< vector holding the matching rec */
- ib_mutex_t rtr_match_mutex;/*!< mutex protect the match_recs
+ mysql_mutex_t rtr_match_mutex;/*!< mutex protect the match_recs
vector */
bool valid; /*!< whether result in matched_recs
or this search is valid (page not
@@ -103,7 +103,7 @@ typedef struct rtr_info{
/*!< vector holding parent pages during
search */
matched_rec_t* matches;/*!< struct holding matching leaf records */
- ib_mutex_t rtr_path_mutex;
+ mysql_mutex_t rtr_path_mutex;
/*!< mutex protect the "path" vector */
buf_block_t* tree_blocks[RTR_MAX_LEVELS + RTR_LEAF_LATCH_NUM];
/*!< tracking pages that would be locked
@@ -137,7 +137,7 @@ typedef struct rtr_info{
struct rtr_info_track_t {
/** Active search info */
std::forward_list<rtr_info_t*, ut_allocator<rtr_info_t*> > rtr_active;
- ib_mutex_t rtr_active_mutex;
+ mysql_mutex_t rtr_active_mutex;
/*!< mutex to protect
rtr_active */
};
diff --git a/storage/innobase/include/hash0hash.h b/storage/innobase/include/hash0hash.h
index 981ff5a0814..eed3107a082 100644
--- a/storage/innobase/include/hash0hash.h
+++ b/storage/innobase/include/hash0hash.h
@@ -26,6 +26,7 @@ Created 5/20/1997 Heikki Tuuri
#pragma once
#include "ut0rnd.h"
+#include "ut0new.h"
struct hash_table_t;
struct hash_cell_t{
diff --git a/storage/innobase/include/ib0mutex.h b/storage/innobase/include/ib0mutex.h
deleted file mode 100644
index b83a1aac419..00000000000
--- a/storage/innobase/include/ib0mutex.h
+++ /dev/null
@@ -1,610 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/******************************************************************//**
-@file include/ib0mutex.h
-Policy based mutexes.
-
-Created 2013-03-26 Sunny Bains.
-***********************************************************************/
-
-#ifndef UNIV_INNOCHECKSUM
-
-#ifndef ib0mutex_h
-#define ib0mutex_h
-
-#include "my_cpu.h"
-
-/** OS mutex for tracking lock/unlock for debugging */
-template <template <typename> class Policy>
-struct OSTrackMutex {
-
- typedef Policy<OSTrackMutex> MutexPolicy;
-
- explicit OSTrackMutex(bool destroy_mutex_at_exit = true)
- UNIV_NOTHROW
- {
- ut_d(m_freed = true);
- ut_d(m_locked = false);
- ut_d(m_destroy_at_exit = destroy_mutex_at_exit);
- }
-
- ~OSTrackMutex() UNIV_NOTHROW
- {
- ut_ad(!m_destroy_at_exit || !m_locked);
- }
-
- /** Initialise the mutex. */
- void init(latch_id_t, const char*, uint32_t) UNIV_NOTHROW
- {
- ut_ad(m_freed);
- ut_ad(!m_locked);
-
- m_mutex.init();
-
- ut_d(m_freed = false);
- }
-
- /** Destroy the mutex */
- void destroy() UNIV_NOTHROW
- {
- ut_ad(!m_locked);
- ut_ad(!m_freed);
-
- m_mutex.destroy();
-
- ut_d(m_freed = true);
- }
-
- /** Release the mutex. */
- void exit() UNIV_NOTHROW
- {
- ut_ad(m_locked);
- ut_d(m_locked = false);
- ut_ad(!m_freed);
-
- m_mutex.exit();
- }
-
- /** Acquire the mutex. */
- void enter(uint32_t, uint32_t, const char*, uint32_t)
- UNIV_NOTHROW
- {
- ut_ad(!m_freed);
-
- m_mutex.enter();
-
- ut_ad(!m_locked);
- ut_d(m_locked = true);
- }
-
- /** @return true if locking succeeded */
- bool try_lock() UNIV_NOTHROW
- {
- ut_ad(!m_freed);
-
- bool locked = m_mutex.try_lock();
-
- if (locked) {
- ut_ad(!m_locked);
- ut_d(m_locked = locked);
- }
-
- return(locked);
- }
-
- /** @return non-const version of the policy */
- MutexPolicy& policy()
- UNIV_NOTHROW
- {
- return(m_policy);
- }
-
- /** @return the const version of the policy */
- const MutexPolicy& policy() const
- UNIV_NOTHROW
- {
- return(m_policy);
- }
-
-private:
-#ifdef UNIV_DEBUG
- /** true if the mutex has not be initialized */
- bool m_freed;
-
- /** true if the mutex has been locked. */
- bool m_locked;
-
- /** Do/Dont destroy mutex at exit */
- bool m_destroy_at_exit;
-#endif /* UNIV_DEBUG */
-
- /** OS Mutex instance */
- OSMutex m_mutex;
-
- /** Policy data */
- MutexPolicy m_policy;
-};
-
-
-#ifdef __linux__
-
-#include <linux/futex.h>
-#include <sys/syscall.h>
-
-/** Mutex implementation that used the Linux futex. */
-template <template <typename> class Policy>
-struct TTASFutexMutex {
-
- typedef Policy<TTASFutexMutex> MutexPolicy;
-
- TTASFutexMutex() UNIV_NOTHROW
- :
- m_lock_word(MUTEX_STATE_UNLOCKED)
- {
- /* Check that lock_word is aligned. */
- ut_ad(!((ulint) &m_lock_word % sizeof(ulint)));
- }
-
- ~TTASFutexMutex()
- {
- ut_ad(m_lock_word.load(std::memory_order_relaxed)
- == MUTEX_STATE_UNLOCKED);
- }
-
- /** Called when the mutex is "created". Note: Not from the constructor
- but when the mutex is initialised. */
- void init(latch_id_t, const char*, uint32_t) UNIV_NOTHROW
- {
- ut_ad(m_lock_word.load(std::memory_order_relaxed)
- == MUTEX_STATE_UNLOCKED);
- }
-
- /** Destroy the mutex. */
- void destroy() UNIV_NOTHROW
- {
- /* The destructor can be called at shutdown. */
- ut_ad(m_lock_word.load(std::memory_order_relaxed)
- == MUTEX_STATE_UNLOCKED);
- }
-
- /** Acquire the mutex.
- @param[in] max_spins max number of spins
- @param[in] max_delay max delay per spin */
- void enter(uint32_t max_spins, uint32_t max_delay,
- const char*, uint32_t) UNIV_NOTHROW
- {
- uint32_t n_spins, n_waits;
-
- for (n_spins= 0; n_spins < max_spins; n_spins++) {
- if (try_lock()) {
- m_policy.add(n_spins, 0);
- return;
- }
-
- ut_delay(max_delay);
- }
-
- for (n_waits= 0;; n_waits++) {
- if (m_lock_word.exchange(MUTEX_STATE_WAITERS,
- std::memory_order_acquire)
- == MUTEX_STATE_UNLOCKED) {
- break;
- }
-
- syscall(SYS_futex, &m_lock_word,
- FUTEX_WAIT_PRIVATE, MUTEX_STATE_WAITERS,
- 0, 0, 0);
- }
-
- m_policy.add(n_spins, n_waits);
- }
-
- /** Release the mutex. */
- void exit() UNIV_NOTHROW
- {
- if (m_lock_word.exchange(MUTEX_STATE_UNLOCKED,
- std::memory_order_release)
- == MUTEX_STATE_WAITERS) {
- syscall(SYS_futex, &m_lock_word, FUTEX_WAKE_PRIVATE,
- 1, 0, 0, 0);
- }
- }
-
- /** Try and lock the mutex.
- @return true if successful */
- bool try_lock() UNIV_NOTHROW
- {
- int32 oldval = MUTEX_STATE_UNLOCKED;
- return m_lock_word.compare_exchange_strong(
- oldval,
- MUTEX_STATE_LOCKED,
- std::memory_order_acquire,
- std::memory_order_relaxed);
- }
-
- /** @return non-const version of the policy */
- MutexPolicy& policy() UNIV_NOTHROW
- {
- return(m_policy);
- }
-
- /** @return const version of the policy */
- const MutexPolicy& policy() const UNIV_NOTHROW
- {
- return(m_policy);
- }
-private:
- /** Policy data */
- MutexPolicy m_policy;
-
- /** lock_word is the target of the atomic test-and-set instruction
- when atomic operations are enabled. */
- std::atomic<int32> m_lock_word;
-};
-
-#endif /* __linux__ */
-
-template <template <typename> class Policy>
-struct TTASMutex {
-
- typedef Policy<TTASMutex> MutexPolicy;
-
- TTASMutex() UNIV_NOTHROW
- :
- m_lock_word(MUTEX_STATE_UNLOCKED)
- {
- /* Check that lock_word is aligned. */
- ut_ad(!((ulint) &m_lock_word % sizeof(ulint)));
- }
-
- ~TTASMutex()
- {
- ut_ad(m_lock_word.load(std::memory_order_relaxed)
- == MUTEX_STATE_UNLOCKED);
- }
-
- /** Called when the mutex is "created". Note: Not from the constructor
- but when the mutex is initialised. */
- void init(latch_id_t) UNIV_NOTHROW
- {
- ut_ad(m_lock_word.load(std::memory_order_relaxed)
- == MUTEX_STATE_UNLOCKED);
- }
-
- /** Destroy the mutex. */
- void destroy() UNIV_NOTHROW
- {
- /* The destructor can be called at shutdown. */
- ut_ad(m_lock_word.load(std::memory_order_relaxed)
- == MUTEX_STATE_UNLOCKED);
- }
-
- /** Try and lock the mutex.
- @return true on success */
- bool try_lock() UNIV_NOTHROW
- {
- uint32_t oldval = MUTEX_STATE_UNLOCKED;
- return m_lock_word.compare_exchange_strong(
- oldval,
- MUTEX_STATE_LOCKED,
- std::memory_order_acquire,
- std::memory_order_relaxed);
- }
-
- /** Release the mutex. */
- void exit() UNIV_NOTHROW
- {
- ut_ad(m_lock_word.load(std::memory_order_relaxed)
- == MUTEX_STATE_LOCKED);
- m_lock_word.store(MUTEX_STATE_UNLOCKED,
- std::memory_order_release);
- }
-
- /** Acquire the mutex.
- @param max_spins max number of spins
- @param max_delay max delay per spin */
- void enter(uint32_t max_spins, uint32_t max_delay,
- const char*, uint32_t) UNIV_NOTHROW
- {
- const uint32_t step = max_spins;
- uint32_t n_spins = 0;
-
- while (!try_lock()) {
- ut_delay(max_delay);
- if (++n_spins == max_spins) {
- os_thread_yield();
- max_spins+= step;
- }
- }
-
- m_policy.add(n_spins, 0);
- }
-
- /** @return non-const version of the policy */
- MutexPolicy& policy() UNIV_NOTHROW
- {
- return(m_policy);
- }
-
- /** @return const version of the policy */
- const MutexPolicy& policy() const UNIV_NOTHROW
- {
- return(m_policy);
- }
-
-private:
- // Disable copying
- TTASMutex(const TTASMutex&);
- TTASMutex& operator=(const TTASMutex&);
-
- /** Policy data */
- MutexPolicy m_policy;
-
- /** mutex state */
- std::atomic<uint32_t> m_lock_word;
-};
-
-/** Mutex interface for all policy mutexes. This class handles the interfacing
-with the Performance Schema instrumentation. */
-template <typename MutexImpl>
-struct PolicyMutex
-{
- typedef typename MutexImpl::MutexPolicy Policy;
-
- PolicyMutex() UNIV_NOTHROW : m_impl()
- {
-#ifdef UNIV_PFS_MUTEX
- m_ptr = 0;
-#endif /* UNIV_PFS_MUTEX */
- }
-
- ~PolicyMutex() { }
-
- /** @return non-const version of the policy */
- Policy& policy() UNIV_NOTHROW
- {
- return(m_impl.policy());
- }
-
- /** @return const version of the policy */
- const Policy& policy() const UNIV_NOTHROW
- {
- return(m_impl.policy());
- }
-
- /** Release the mutex. */
- void exit() UNIV_NOTHROW
- {
-#ifdef UNIV_PFS_MUTEX
- pfs_exit();
-#endif /* UNIV_PFS_MUTEX */
-
- ut_d(policy().context.release(m_impl));
-
- m_impl.exit();
- }
-
- /** Acquire the mutex.
- @param n_spins max number of spins
- @param n_delay max delay per spin
- @param name filename where locked
- @param line line number where locked */
- void enter(
- uint32_t n_spins,
- uint32_t n_delay,
- const char* name,
- uint32_t line) UNIV_NOTHROW
- {
-#ifdef UNIV_PFS_MUTEX
- /* Note: locker is really an alias for state. That's why
- it has to be in the same scope during pfs_end(). */
-
- PSI_mutex_locker_state state;
- PSI_mutex_locker* locker;
-
- locker = pfs_begin_lock(&state, name, line);
-#endif /* UNIV_PFS_MUTEX */
-
- ut_d(policy().context.enter(m_impl, name, line));
-
- m_impl.enter(n_spins, n_delay, name, line);
-
- ut_d(policy().context.locked(m_impl, name, line));
-#ifdef UNIV_PFS_MUTEX
- pfs_end(locker, 0);
-#endif /* UNIV_PFS_MUTEX */
- }
-
- /** Try and lock the mutex, return 0 on SUCCESS and 1 otherwise.
- @param name filename where locked
- @param line line number where locked */
- int trylock(const char* name, uint32_t line) UNIV_NOTHROW
- {
-#ifdef UNIV_PFS_MUTEX
- /* Note: locker is really an alias for state. That's why
- it has to be in the same scope during pfs_end(). */
-
- PSI_mutex_locker_state state;
- PSI_mutex_locker* locker;
-
- locker = pfs_begin_trylock(&state, name, line);
-#endif /* UNIV_PFS_MUTEX */
-
- /* There is a subtlety here, we check the mutex ordering
- after locking here. This is only done to avoid add and
- then remove if the trylock was unsuccesful. */
-
- int ret = m_impl.try_lock() ? 0 : 1;
-
- if (ret == 0) {
-
- ut_d(policy().context.enter(m_impl, name, line));
-
- ut_d(policy().context.locked(m_impl, name, line));
- }
-
-#ifdef UNIV_PFS_MUTEX
- pfs_end(locker, 0);
-#endif /* UNIV_PFS_MUTEX */
-
- return(ret);
- }
-
-#ifdef UNIV_DEBUG
- /** @return true if the thread owns the mutex. */
- bool is_owned() const UNIV_NOTHROW
- {
- return(policy().context.is_owned());
- }
-#endif /* UNIV_DEBUG */
-
- /**
- Initialise the mutex.
-
- @param[in] id Mutex ID
- @param[in] filename file where created
- @param[in] line line number in file where created */
- void init(
- latch_id_t id,
- const char* filename,
- uint32_t line)
- UNIV_NOTHROW
- {
-#ifdef UNIV_PFS_MUTEX
- pfs_add(sync_latch_get_pfs_key(id));
-#endif /* UNIV_PFS_MUTEX */
-
- m_impl.init(id, filename, line);
- policy().init(m_impl, id, filename, line);
- ut_d(policy().context.init(id));
- }
-
- /** Free resources (if any) */
- void destroy() UNIV_NOTHROW
- {
-#ifdef UNIV_PFS_MUTEX
- pfs_del();
-#endif /* UNIV_PFS_MUTEX */
- m_impl.destroy();
- policy().destroy();
- ut_d(policy().context.destroy());
- }
-
- /** Required for os_event_t */
- operator sys_mutex_t*() UNIV_NOTHROW
- {
- return(m_impl.operator sys_mutex_t*());
- }
-
-#ifdef UNIV_PFS_MUTEX
- /** Performance schema monitoring - register mutex with PFS.
-
- Note: This is public only because we want to get around an issue
- with registering a subset of buffer pool pages with PFS when
- PFS_GROUP_BUFFER_SYNC is defined. Therefore this has to then
- be called by external code (see buf0buf.cc).
-
- @param key - Performance Schema key. */
- void pfs_add(mysql_pfs_key_t key) UNIV_NOTHROW
- {
- ut_ad(m_ptr == 0);
- m_ptr = PSI_MUTEX_CALL(init_mutex)(key, this);
- }
-
-private:
-
- /** Performance schema monitoring.
- @param state - PFS locker state
- @param name - file name where locked
- @param line - line number in file where locked */
- PSI_mutex_locker* pfs_begin_lock(
- PSI_mutex_locker_state* state,
- const char* name,
- uint32_t line) UNIV_NOTHROW
- {
- if (m_ptr != 0) {
- return(PSI_MUTEX_CALL(start_mutex_wait)(
- state, m_ptr,
- PSI_MUTEX_LOCK, name, (uint) line));
- }
-
- return(0);
- }
-
- /** Performance schema monitoring.
- @param state - PFS locker state
- @param name - file name where locked
- @param line - line number in file where locked */
- PSI_mutex_locker* pfs_begin_trylock(
- PSI_mutex_locker_state* state,
- const char* name,
- uint32_t line) UNIV_NOTHROW
- {
- if (m_ptr != 0) {
- return(PSI_MUTEX_CALL(start_mutex_wait)(
- state, m_ptr,
- PSI_MUTEX_TRYLOCK, name, (uint) line));
- }
-
- return(0);
- }
-
- /** Performance schema monitoring
- @param locker - PFS identifier
- @param ret - 0 for success and 1 for failure */
- void pfs_end(PSI_mutex_locker* locker, int ret) UNIV_NOTHROW
- {
- if (locker != 0) {
- PSI_MUTEX_CALL(end_mutex_wait)(locker, ret);
- }
- }
-
- /** Performance schema monitoring - register mutex release */
- void pfs_exit()
- {
- if (m_ptr != 0) {
- PSI_MUTEX_CALL(unlock_mutex)(m_ptr);
- }
- }
-
- /** Performance schema monitoring - deregister */
- void pfs_del()
- {
- if (m_ptr != 0) {
- PSI_MUTEX_CALL(destroy_mutex)(m_ptr);
- m_ptr = 0;
- }
- }
-#endif /* UNIV_PFS_MUTEX */
-
-private:
- /** The mutex implementation */
- MutexImpl m_impl;
-
-#ifdef UNIV_PFS_MUTEX
- /** The performance schema instrumentation hook. */
- PSI_mutex* m_ptr;
-#endif /* UNIV_PFS_MUTEX */
-
-};
-
-#endif /* ib0mutex_h */
-
-#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index d224c216f04..910db0ab8ec 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -706,9 +706,15 @@ class lock_sys_t
{
bool m_initialised;
-public:
+ /** The my_hrtime_coarse().val of the oldest mutex_lock_wait() start, or 0 */
+ std::atomic<ulonglong> mutex_wait_start;
+
/** mutex proteting the locks */
MY_ALIGNED(CACHE_LINE_SIZE) mysql_mutex_t mutex;
+public:
+ /** Diagnostic message for exceeding the mutex_lock_wait() timeout */
+ static const char fatal_msg[];
+
/** record locks */
hash_table_t rec_hash;
/** predicate locks for SPATIAL INDEX */
@@ -741,6 +747,38 @@ public:
bool is_initialised() { return m_initialised; }
+private:
+ /** Acquire lock_sys.mutex */
+ ATTRIBUTE_NOINLINE void mutex_lock_wait();
+public:
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ /** Try to acquire lock_sys.mutex */
+ ATTRIBUTE_NOINLINE int mutex_trylock();
+ /** Acquire lock_sys.mutex */
+ ATTRIBUTE_NOINLINE void mutex_lock();
+ /** Release lock_sys.mutex */
+ ATTRIBUTE_NOINLINE void mutex_unlock();
+#else
+ /** Try to acquire lock_sys.mutex */
+ int mutex_trylock() { return mysql_mutex_trylock(&mutex); }
+ /** Aqcuire lock_sys.mutex */
+ void mutex_lock() { if (mutex_trylock()) mutex_lock_wait(); }
+ /** Release lock_sys.mutex */
+ void mutex_unlock() { mysql_mutex_unlock(&mutex); }
+#endif
+ /** Assert that mutex_lock() has been invoked */
+ void mutex_assert_locked() const { mysql_mutex_assert_owner(&mutex); }
+ /** Assert that mutex_lock() has not been invoked */
+ void mutex_assert_unlocked() const { mysql_mutex_assert_not_owner(&mutex); }
+
+ /** @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); }
+
+ /** Wait for a lock to be granted */
+ void wait_lock(lock_t **lock, mysql_cond_t *cond)
+ { while (*lock) mysql_cond_wait(cond, &mutex); }
/**
Creates the lock system at database start.
diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h
index 226c9f84cbb..aa1cb964e53 100644
--- a/storage/innobase/include/lock0priv.h
+++ b/storage/innobase/include/lock0priv.h
@@ -629,7 +629,7 @@ inline void lock_set_lock_and_trx_wait(lock_t* lock, trx_t* trx)
ut_ad(lock);
ut_ad(lock->trx == trx);
ut_ad(trx->lock.wait_lock == NULL);
- mysql_mutex_assert_owner(&lock_sys.mutex);
+ lock_sys.mutex_assert_locked();
trx->lock.wait_lock = lock;
lock->type_mode |= LOCK_WAIT;
@@ -640,7 +640,7 @@ inline void lock_set_lock_and_trx_wait(lock_t* lock, trx_t* trx)
inline void lock_reset_lock_and_trx_wait(lock_t* lock)
{
ut_ad(lock_get_wait(lock));
- mysql_mutex_assert_owner(&lock_sys.mutex);
+ lock_sys.mutex_assert_locked();
ut_ad(lock->trx->lock.wait_lock == NULL
|| lock->trx->lock.wait_lock == lock);
lock->trx->lock.wait_lock = NULL;
diff --git a/storage/innobase/include/lock0priv.ic b/storage/innobase/include/lock0priv.ic
index 0930a8e5932..23e84b15e95 100644
--- a/storage/innobase/include/lock0priv.ic
+++ b/storage/innobase/include/lock0priv.ic
@@ -131,7 +131,7 @@ lock_rec_get_next(
ulint heap_no,/*!< in: heap number of the record */
lock_t* lock) /*!< in: lock */
{
- mysql_mutex_assert_owner(&lock_sys.mutex);
+ lock_sys.mutex_assert_locked();
do {
ut_ad(lock_get_type_low(lock) == LOCK_REC);
@@ -206,7 +206,7 @@ lock_rec_get_next_on_page_const(
/*============================*/
const lock_t* lock) /*!< in: a record lock */
{
- mysql_mutex_assert_owner(&lock_sys.mutex);
+ lock_sys.mutex_assert_locked();
ut_ad(lock_get_type_low(lock) == LOCK_REC);
const page_id_t page_id(lock->un_member.rec_lock.page_id);
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index 0cf7470682c..aebe511d659 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -27,7 +27,6 @@ Created 12/9/1995 Heikki Tuuri
#include "mach0data.h"
#include "assume_aligned.h"
#include "ut0crc32.h"
-#include "sync0debug.h"
extern ulong srv_log_buffer_size;
@@ -305,17 +304,6 @@ log_free_check(void)
are holding some latches. This is OK, as long as we are not holding
any latches on buffer blocks. */
-#ifdef UNIV_DEBUG
- static const latch_level_t latches[] = {
- SYNC_DICT, /* dict_sys.mutex during
- commit_try_rebuild() */
- };
-#endif /* UNIV_DEBUG */
-
- ut_ad(!sync_check_iterate(
- sync_allowed_latches(latches,
- latches + UT_ARR_SIZE(latches))));
-
if (log_sys.check_flush_or_checkpoint()) {
log_check_margins();
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index d29c8849b1b..c7e31f2d336 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -26,11 +26,10 @@ Created 9/20/1997 Heikki Tuuri
#pragma once
-#include "ut0byte.h"
+#include "ut0new.h"
#include "buf0types.h"
#include "log0log.h"
#include "mtr0types.h"
-#include "ut0mutex.h"
#include <deque>
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 9236bbef05d..9906daf3eb9 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -24,6 +24,8 @@ The memory management
Created 6/8/1994 Heikki Tuuri
*************************************************************************/
+#include "ut0new.h"
+
#ifdef UNIV_DEBUG
# define mem_heap_create_block(heap, n, type, file_name, line) \
mem_heap_create_block_func(heap, n, file_name, line, type)
diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h
index b5cfcadbe75..5445dc0a763 100644
--- a/storage/innobase/include/mtr0types.h
+++ b/storage/innobase/include/mtr0types.h
@@ -24,14 +24,11 @@ Mini-transaction buffer global types
Created 11/26/1995 Heikki Tuuri
*******************************************************/
-#ifndef mtr0types_h
-#define mtr0types_h
+#pragma once
-#ifndef UNIV_INNOCHECKSUM
#include "buf0types.h"
-#else
-#include "univ.i"
-#endif /* UNIV_INNOCHECKSUM */
+
+#include "ut0byte.h"
struct mtr_t;
@@ -344,6 +341,4 @@ enum mtr_memo_type_t {
/** wr_lock() on fil_space_t::latch */
MTR_MEMO_SPACE_S_LOCK = MTR_MEMO_SX_LOCK << 2
};
-#endif /* !UNIV_CHECKSUM */
-
-#endif /* mtr0types_h */
+#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h
index d784f624b07..f9eb4b15745 100644
--- a/storage/innobase/include/os0thread.h
+++ b/storage/innobase/include/os0thread.h
@@ -59,11 +59,6 @@ extern "C" { typedef void* (*os_thread_func_t)(void*); }
/* Define a function pointer type to use in a typecast */
typedef void* (*os_posix_f_t) (void*);
-#ifdef HAVE_PSI_INTERFACE
-/* Define for performance schema registration key */
-typedef unsigned int mysql_pfs_key_t;
-#endif /* HAVE_PSI_INTERFACE */
-
#define os_thread_eq(a,b) IF_WIN(a == b, pthread_equal(a, b))
#define os_thread_yield() IF_WIN(SwitchToThread(), sched_yield())
#define os_thread_get_curr_id() IF_WIN(GetCurrentThreadId(), pthread_self())
diff --git a/storage/innobase/include/page0types.h b/storage/innobase/include/page0types.h
index 6c5a681f3b5..4d6aabfd576 100644
--- a/storage/innobase/include/page0types.h
+++ b/storage/innobase/include/page0types.h
@@ -30,6 +30,7 @@ Created 2/2/1994 Heikki Tuuri
#include "dict0types.h"
#include "mtr0types.h"
#include "rem0types.h"
+#include "ut0new.h"
#include <map>
diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic
index ede61283f33..87af2cc3879 100644
--- a/storage/innobase/include/page0zip.ic
+++ b/storage/innobase/include/page0zip.ic
@@ -324,11 +324,7 @@ void
page_zip_reset_stat_per_index()
/*===========================*/
{
- mutex_enter(&page_zip_stat_per_index_mutex);
-
- page_zip_stat_per_index.erase(
- page_zip_stat_per_index.begin(),
- page_zip_stat_per_index.end());
-
- mutex_exit(&page_zip_stat_per_index_mutex);
+ mysql_mutex_lock(&page_zip_stat_per_index_mutex);
+ page_zip_stat_per_index.clear();
+ mysql_mutex_unlock(&page_zip_stat_per_index_mutex);
}
diff --git a/storage/innobase/include/read0types.h b/storage/innobase/include/read0types.h
index 21143ab609d..521097b5298 100644
--- a/storage/innobase/include/read0types.h
+++ b/storage/innobase/include/read0types.h
@@ -24,13 +24,15 @@ Cursor read
Created 2/16/1997 Heikki Tuuri
*******************************************************/
-#ifndef read0types_h
-#define read0types_h
+#pragma once
#include "dict0mem.h"
#include "trx0types.h"
#include <algorithm>
+#ifdef UNIV_PFS_MUTEX
+extern mysql_pfs_key_t read_view_mutex_key;
+#endif
/**
Read view lists the trx ids of those transactions for which a consistent read
@@ -190,7 +192,7 @@ class ReadView: public ReadViewBase
std::atomic<bool> m_open;
/** For synchronisation with purge coordinator. */
- mutable ib_mutex_t m_mutex;
+ mutable mysql_mutex_t m_mutex;
/**
trx id of creating transaction.
@@ -199,8 +201,9 @@ class ReadView: public ReadViewBase
trx_id_t m_creator_trx_id;
public:
- ReadView(): m_open(false) { mutex_create(LATCH_ID_READ_VIEW, &m_mutex); }
- ~ReadView() { mutex_free(&m_mutex); }
+ ReadView(): m_open(false)
+ { mysql_mutex_init(read_view_mutex_key, &m_mutex, nullptr); }
+ ~ReadView() { mysql_mutex_destroy(&m_mutex); }
/**
@@ -248,12 +251,12 @@ public:
*/
void print_limits(FILE *file) const
{
- mutex_enter(&m_mutex);
+ mysql_mutex_lock(&m_mutex);
if (is_open())
fprintf(file, "Trx read view will not see trx with"
" id >= " TRX_ID_FMT ", sees < " TRX_ID_FMT "\n",
low_limit_id(), up_limit_id());
- mutex_exit(&m_mutex);
+ mysql_mutex_unlock(&m_mutex);
}
@@ -271,23 +274,19 @@ public:
*/
void append_to(ReadViewBase *to) const
{
- mutex_enter(&m_mutex);
+ mysql_mutex_lock(&m_mutex);
if (is_open())
to->append(*this);
- mutex_exit(&m_mutex);
+ mysql_mutex_unlock(&m_mutex);
}
-
/**
Declare the object mostly unaccessible.
- innodb_monitor_set_option is operating also on freed transaction objects.
*/
void mem_noaccess() const
{
MEM_NOACCESS(&m_open, sizeof m_open);
- /* m_mutex is accessed by innodb_show_mutex_status()
- and innodb_monitor_update() even after trx_t::free() */
+ /* m_mutex is accessed via trx_sys.rw_trx_hash */
MEM_NOACCESS(&m_creator_trx_id, sizeof m_creator_trx_id);
}
};
-#endif
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 18114f18b14..6d189b6e580 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -316,11 +316,18 @@ data dictionary modification operation. */
void
row_mysql_lock_data_dictionary_func(
/*================================*/
- trx_t* trx, /*!< in/out: transaction */
+#ifdef UNIV_PFS_RWLOCK
const char* file, /*!< in: file name */
- unsigned line); /*!< in: line number */
+ unsigned line, /*!< in: line number */
+#endif
+ trx_t* trx); /*!< in/out: transaction */
+#ifdef UNIV_PFS_RWLOCK
#define row_mysql_lock_data_dictionary(trx) \
- row_mysql_lock_data_dictionary_func(trx, __FILE__, __LINE__)
+ row_mysql_lock_data_dictionary_func(__FILE__, __LINE__, trx)
+#else
+#define row_mysql_lock_data_dictionary row_mysql_lock_data_dictionary_func
+#endif
+
/*********************************************************************//**
Unlocks the data dictionary exclusive lock. */
void
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index 6f75cdc0b64..66a91b87d60 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -38,7 +38,6 @@ Created 12/15/2009 Jimmy Yang
#include <stdint.h>
#include "my_atomic.h"
-#include "my_atomic_wrapper.h"
/** Possible status values for "mon_status" in "struct monitor_value" */
enum monitor_running_status {
@@ -419,10 +418,6 @@ enum monitor_id_t {
MONITOR_ICP_OUT_OF_RANGE,
MONITOR_ICP_MATCH,
- /* Mutex/RW-Lock related counters */
- MONITOR_MODULE_LATCHES,
- MONITOR_LATCHES,
-
/* This is used only for control system to turn
on/off and reset all monitor counters */
MONITOR_ALL_COUNTER,
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 5aedd122a0f..8b87cb9014c 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -52,6 +52,29 @@ Created 10/10/1995 Heikki Tuuri
#include <tpool.h>
#include <memory>
+/** Simple non-atomic counter
+@tparam Type the integer type of the counter */
+template <typename Type>
+struct MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) simple_counter
+{
+ /** Increment the counter */
+ Type inc() { return add(1); }
+ /** Decrement the counter */
+ Type dec() { return add(Type(~0)); }
+
+ /** Add to the counter
+ @param i amount to be added
+ @return the value of the counter after adding */
+ Type add(Type i) { return m_counter += i; }
+
+ /** @return the value of the counter */
+ operator Type() const { return m_counter; }
+
+private:
+ /** The counter */
+ Type m_counter;
+};
+
/** Global counters used inside InnoDB. */
struct srv_stats_t
{
@@ -210,15 +233,13 @@ at a time */
#define SRV_AUTO_EXTEND_INCREMENT (srv_sys_space.get_autoextend_increment())
/** Mutex protecting page_zip_stat_per_index */
-extern ib_mutex_t page_zip_stat_per_index_mutex;
-/* Mutex for locking srv_monitor_file. Not created if srv_read_only_mode */
-extern ib_mutex_t srv_monitor_file_mutex;
+extern mysql_mutex_t page_zip_stat_per_index_mutex;
+/** Mutex for locking srv_monitor_file */
+extern mysql_mutex_t srv_monitor_file_mutex;
/* Temporary file for innodb monitor output */
extern FILE* srv_monitor_file;
-/* Mutex for locking srv_misc_tmpfile. Only created if !srv_read_only_mode.
-This mutex has a very low rank; threads reserving it should not
-acquire any further latches or sleep before releasing this one. */
-extern ib_mutex_t srv_misc_tmpfile_mutex;
+/** Mutex for locking srv_misc_tmpfile */
+extern mysql_mutex_t srv_misc_tmpfile_mutex;
/* Temporary file for miscellanous diagnostic output */
extern FILE* srv_misc_tmpfile;
@@ -454,7 +475,6 @@ extern ulint srv_log_writes_and_flush;
#ifdef UNIV_DEBUG
extern my_bool innodb_evict_tables_on_commit_debug;
-extern my_bool srv_sync_debug;
extern my_bool srv_purge_view_update_only_debug;
/** Value of MySQL global used to disable master thread. */
@@ -480,9 +500,6 @@ extern uint srv_n_purge_threads;
/* the number of pages to purge in one batch */
extern ulong srv_purge_batch_size;
-/* the number of sync wait arrays */
-extern ulong srv_sync_array_size;
-
/* print all user-level transactions deadlocks to mysqld stderr */
extern my_bool srv_print_all_deadlocks;
diff --git a/storage/innobase/include/sync0debug.h b/storage/innobase/include/sync0debug.h
deleted file mode 100644
index 1ccf95ea3a8..00000000000
--- a/storage/innobase/include/sync0debug.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
-
-Portions of this file contain modifications contributed and copyrighted by
-Google, Inc. Those modifications are gratefully acknowledged and are described
-briefly in the InnoDB documentation. The contributions by Google are
-incorporated with their permission, and subject to the conditions contained in
-the file COPYING.Google.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/sync0debug.h
-Debug checks for latches, header file
-
-Created 2012-08-21 Sunny Bains
-*******************************************************/
-
-#ifndef sync0debug_h
-#define sync0debug_h
-
-#include "univ.i"
-
-/** Initializes the synchronization data structures. */
-void
-sync_check_init();
-
-/** Free the InnoDB synchronization data structures. */
-void
-sync_check_close();
-
-#ifdef UNIV_DEBUG
-/** Check if it is OK to acquire the latch.
-@param[in] latch latch type */
-void
-sync_check_lock_validate(const latch_t* latch);
-
-/** Note that the lock has been granted
-@param[in] latch latch type */
-void
-sync_check_lock_granted(const latch_t* latch);
-
-/** Removes a latch from the thread level array if it is found there.
-@param[in] latch to unlock */
-void
-sync_check_unlock(const latch_t* latch);
-
-/** Checks if the level array for the current thread contains a
-mutex or rw-latch at the specified level.
-@param[in] level to find
-@return a matching latch, or NULL if not found */
-const latch_t*
-sync_check_find(latch_level_t level);
-
-/** Checks that the level array for the current thread is empty.
-Terminate iteration if the functor returns true.
-@param[in] functor called for each element.
-@return true if the functor returns true for any element */
-bool
-sync_check_iterate(const sync_check_functor_t& functor);
-
-#endif /* UNIV_DEBUG */
-
-#endif /* !sync0debug_h */
diff --git a/storage/innobase/include/sync0policy.h b/storage/innobase/include/sync0policy.h
deleted file mode 100644
index 68397827891..00000000000
--- a/storage/innobase/include/sync0policy.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/******************************************************************//**
-@file include/sync0policy.h
-Policies for mutexes.
-
-Created 2012-08-21 Sunny Bains.
-***********************************************************************/
-
-#ifndef sync0policy_h
-#define sync0policy_h
-
-#include "ut0rnd.h"
-#include "os0thread.h"
-#include "srv0mon.h"
-#include "sync0debug.h"
-
-#ifdef UNIV_DEBUG
-
-template <typename Mutex> class MutexDebug: public latch_t
-{
- /** Mutex to check for lock order violation */
- const Mutex *m_mutex;
- /** Filename from where enter was called */
- const char *m_filename;
- /** Line mumber in filename */
- unsigned m_line;
- /** Thread ID of the thread that owns the mutex */
- os_thread_id_t m_thread_id;
- /** Mutex protecting the above members */
- mutable OSMutex m_debug_mutex;
-
-
- void set(const Mutex *mutex, const char *filename, unsigned line,
- os_thread_id_t thread_id)
- {
- m_debug_mutex.enter();
- m_mutex= mutex;
- m_filename= filename;
- m_line= line;
- m_thread_id= thread_id;
- m_debug_mutex.exit();
- }
-
-
- const MutexDebug get() const
- {
- MutexDebug ret;
- m_debug_mutex.enter();
- ret.m_mutex= m_mutex;
- ret.m_filename= m_filename;
- ret.m_line= m_line;
- ret.m_thread_id= m_thread_id;
- m_debug_mutex.exit();
- return ret;
- }
-
-
- /**
- Called either when mutex is locked or destroyed. Thus members are protected
- from concurrent modification.
- */
- void assert_clean_context()
- {
- ut_ad(!m_mutex);
- ut_ad(!m_filename);
- ut_ad(!m_line);
- ut_ad(m_thread_id == os_thread_id_t(ULINT_UNDEFINED));
- }
-
-
-public:
- /**
- Called when the mutex is "created". Note: Not from the constructor
- but when the mutex is initialised.
- @param[in] id Mutex ID
- */
- void init(latch_id_t id)
- {
- ut_ad(id != LATCH_ID_NONE);
- m_id= id;
- m_debug_mutex.init();
- set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
- }
-
-
- /** Mutex is being destroyed. */
- void destroy()
- {
- assert_clean_context();
- m_debug_mutex.destroy();
- }
-
-
- /**
- Called when an attempt is made to lock the mutex
- @param[in] mutex Mutex instance to be locked
- @param[in] filename Filename from where it was called
- @param[in] line Line number from where it was called
- */
- void enter(const Mutex &mutex, const char *filename, unsigned line)
- {
- MutexDebug context;
- ut_ad(!is_owned());
- context.init(m_id);
- context.set(&mutex, filename, line, os_thread_get_curr_id());
- /* Check for latch order violation. */
- sync_check_lock_validate(&context);
- context.set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
- context.destroy();
- }
-
-
- /**
- Called when the mutex is locked
- @param[in] mutex Mutex instance that was locked
- @param[in] filename Filename from where it was called
- @param[in] line Line number from where it was called
- */
- void locked(const Mutex &mutex, const char *filename, unsigned line)
- {
- assert_clean_context();
- set(&mutex, filename, line, os_thread_get_curr_id());
- sync_check_lock_granted(this);
- }
-
-
- /**
- Called when the mutex is released
- @param[in] mutex Mutex that was released
- */
- void release(const Mutex &mutex)
- {
- ut_ad(is_owned());
- set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
- sync_check_unlock(this);
- }
-
-
- /** @return true if thread owns the mutex */
- bool is_owned() const
- {
- return os_thread_eq(get_thread_id(), os_thread_get_curr_id());
- }
-
-
- /** @return the name of the file from the mutex was acquired */
- const char* get_enter_filename() const { return get().m_filename; }
-
-
- /** @return the name of the file from the mutex was acquired */
- unsigned get_enter_line() const { return get().m_line; }
-
-
- /** @return id of the thread that was trying to acquire the mutex */
- os_thread_id_t get_thread_id() const { return get().m_thread_id; }
-
-
- /**
- Print information about the latch
- @return the string representation
- */
- virtual std::string to_string() const
- {
- std::ostringstream msg;
- const MutexDebug ctx= get();
-
- msg << m_mutex->policy().to_string();
- if (ctx.m_mutex)
- msg << " addr: " << ctx.m_mutex << " acquired: "
- << sync_basename(ctx.get_enter_filename()) << ":"
- << ctx.get_enter_line();
- else
- msg << "Not locked";
-
- return(msg.str());
- }
-};
-#endif /* UNIV_DEBUG */
-
-/** Collect the metrics per mutex instance, no aggregation. */
-template <typename Mutex>
-struct GenericPolicy
-{
-public:
- /** Called when the mutex is "created". Note: Not from the constructor
- but when the mutex is initialised.
- @param[in] id Mutex ID
- @param[in] filename File where mutex was created
- @param[in] line Line in filename */
- void init(
- const Mutex&,
- latch_id_t id,
- const char* filename,
- uint32_t line)
- UNIV_NOTHROW
- {
- m_id = id;
-
- latch_meta_t& meta = sync_latch_get_meta(id);
-
- ut_ad(meta.get_id() == id);
-
- meta.get_counter()->single_register(&m_count);
-
- m_filename = filename;
- m_line = line;
- }
-
- /** Called when the mutex is destroyed. */
- void destroy()
- UNIV_NOTHROW
- {
- latch_meta_t& meta = sync_latch_get_meta(m_id);
-
- meta.get_counter()->single_deregister(&m_count);
- }
-
- /** Called after a successful mutex acquire.
- @param[in] n_spins Number of times the thread did
- spins while trying to acquire the mutex
- @param[in] n_waits Number of times the thread waited
- in some type of OS queue */
- void add(
- uint32_t n_spins,
- uint32_t n_waits)
- UNIV_NOTHROW
- {
- /* Currently global on/off. Keeps things simple and fast */
-
- if (!m_count.m_enabled) {
-
- return;
- }
-
- m_count.m_spins += n_spins;
- m_count.m_waits += n_waits;
-
- ++m_count.m_calls;
- }
-
- /** Print the information about the latch
- @return the string representation */
- std::string print() const
- UNIV_NOTHROW;
-
- /** @return the latch ID */
- latch_id_t get_id() const
- UNIV_NOTHROW
- {
- return(m_id);
- }
-
-
- /** @return the string representation */
- std::string to_string() const
- {
- return sync_mutex_to_string(get_id(),
- std::string(m_filename)
- .append(":")
- .append(std::to_string(m_line)));
- }
-
-#ifdef UNIV_DEBUG
- MutexDebug<Mutex> context;
-#endif
-
-private:
- const char *m_filename;
- uint32_t m_line;
-
- /** The user visible counters, registered with the meta-data. */
- latch_meta_t::CounterType::Count m_count;
-
- /** Latch meta data ID */
- latch_id_t m_id;
-};
-
-#endif /* sync0policy_h */
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
deleted file mode 100644
index 2d45b03e908..00000000000
--- a/storage/innobase/include/sync0sync.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2008, Google Inc.
-Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2020, MariaDB Corporation.
-
-Portions of this file contain modifications contributed and copyrighted by
-Google, Inc. Those modifications are gratefully acknowledged and are described
-briefly in the InnoDB documentation. The contributions by Google are
-incorporated with their permission, and subject to the conditions contained in
-the file COPYING.Google.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/sync0sync.h
-Mutex, the basic synchronization primitive
-
-Created 9/5/1995 Heikki Tuuri
-*******************************************************/
-
-#ifndef sync0sync_h
-#define sync0sync_h
-
-#include "univ.i"
-
-#ifdef UNIV_PFS_MUTEX
-/* Key defines to register InnoDB mutexes with performance schema */
-extern mysql_pfs_key_t buf_pool_mutex_key;
-extern mysql_pfs_key_t dict_foreign_err_mutex_key;
-extern mysql_pfs_key_t dict_sys_mutex_key;
-extern mysql_pfs_key_t fil_system_mutex_key;
-extern mysql_pfs_key_t flush_list_mutex_key;
-extern mysql_pfs_key_t fts_cache_mutex_key;
-extern mysql_pfs_key_t fts_cache_init_mutex_key;
-extern mysql_pfs_key_t fts_delete_mutex_key;
-extern mysql_pfs_key_t fts_doc_id_mutex_key;
-extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
-extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
-extern mysql_pfs_key_t ibuf_mutex_key;
-extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
-extern mysql_pfs_key_t log_sys_mutex_key;
-extern mysql_pfs_key_t log_cmdq_mutex_key;
-extern mysql_pfs_key_t log_flush_order_mutex_key;
-extern mysql_pfs_key_t recalc_pool_mutex_key;
-extern mysql_pfs_key_t purge_sys_pq_mutex_key;
-extern mysql_pfs_key_t recv_sys_mutex_key;
-extern mysql_pfs_key_t rtr_active_mutex_key;
-extern mysql_pfs_key_t rtr_match_mutex_key;
-extern mysql_pfs_key_t rtr_path_mutex_key;
-extern mysql_pfs_key_t redo_rseg_mutex_key;
-extern mysql_pfs_key_t noredo_rseg_mutex_key;
-extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
-extern mysql_pfs_key_t srv_innodb_monitor_mutex_key;
-extern mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
-extern mysql_pfs_key_t srv_monitor_file_mutex_key;
-extern mysql_pfs_key_t buf_dblwr_mutex_key;
-extern mysql_pfs_key_t trx_pool_mutex_key;
-extern mysql_pfs_key_t trx_pool_manager_mutex_key;
-extern mysql_pfs_key_t lock_mutex_key;
-extern mysql_pfs_key_t lock_wait_mutex_key;
-extern mysql_pfs_key_t trx_sys_mutex_key;
-extern mysql_pfs_key_t srv_threads_mutex_key;
-extern mysql_pfs_key_t sync_array_mutex_key;
-extern mysql_pfs_key_t thread_mutex_key;
-extern mysql_pfs_key_t row_drop_list_mutex_key;
-extern mysql_pfs_key_t rw_trx_hash_element_mutex_key;
-extern mysql_pfs_key_t read_view_mutex_key;
-#endif /* UNIV_PFS_MUTEX */
-
-#ifdef UNIV_PFS_RWLOCK
-/* Following are rwlock keys used to register with MySQL
-performance schema */
-extern mysql_pfs_key_t dict_operation_lock_key;
-extern mysql_pfs_key_t fil_space_latch_key;
-extern mysql_pfs_key_t trx_i_s_cache_lock_key;
-extern mysql_pfs_key_t trx_purge_latch_key;
-extern mysql_pfs_key_t index_tree_rw_lock_key;
-extern mysql_pfs_key_t index_online_log_key;
-extern mysql_pfs_key_t trx_sys_rw_lock_key;
-#endif /* UNIV_PFS_RWLOCK */
-
-#endif /* !sync0sync_h */
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
deleted file mode 100644
index f8df704c9d9..00000000000
--- a/storage/innobase/include/sync0types.h
+++ /dev/null
@@ -1,967 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/**************************************************//**
-@file include/sync0types.h
-Global types for sync
-
-Created 9/5/1995 Heikki Tuuri
-*******************************************************/
-
-#ifndef sync0types_h
-#define sync0types_h
-
-#include <vector>
-
-#include "ut0new.h"
-
-#ifdef _WIN32
-/** Native mutex */
-typedef CRITICAL_SECTION sys_mutex_t;
-#else
-/** Native mutex */
-typedef pthread_mutex_t sys_mutex_t;
-#endif /* _WIN32 */
-
-/** Mutex states. */
-enum mutex_state_t {
- /** Mutex is free */
- MUTEX_STATE_UNLOCKED = 0,
-
- /** Mutex is acquired by some thread. */
- MUTEX_STATE_LOCKED = 1,
-
- /** Mutex is contended and there are threads waiting on the lock. */
- MUTEX_STATE_WAITERS = 2
-};
-
-/*
- LATCHING ORDER WITHIN THE DATABASE
- ==================================
-
-The mutex or latch in the central memory object, for instance, a rollback
-segment object, must be acquired before acquiring the latch or latches to
-the corresponding file data structure. In the latching order below, these
-file page object latches are placed immediately below the corresponding
-central memory object latch or mutex.
-
-Synchronization object Notes
----------------------- -----
-
-Dictionary mutex If we have a pointer to a dictionary
-| object, e.g., a table, it can be
-| accessed without reserving the
-| dictionary mutex. We must have a
-| reservation, a memoryfix, to the
-| appropriate table object in this case,
-| and the table must be explicitly
-| released later.
-V
-Dictionary header
-|
-V
-Secondary index tree latch The tree latch protects also all
-| the B-tree non-leaf pages. These
-V can be read with the page only
-Secondary index non-leaf bufferfixed to save CPU time,
-| no s-latch is needed on the page.
-| Modification of a page requires an
-| x-latch on the page, however. If a
-| thread owns an x-latch to the tree,
-| it is allowed to latch non-leaf pages
-| even after it has acquired the fsp
-| latch.
-V
-Secondary index leaf The latch on the secondary index leaf
-| can be kept while accessing the
-| clustered index, to save CPU time.
-V
-Clustered index tree latch To increase concurrency, the tree
-| latch is usually released when the
-| leaf page latch has been acquired.
-V
-Clustered index non-leaf
-|
-V
-Clustered index leaf
-|
-V
-Transaction system header
-|
-V
-Rollback segment mutex The rollback segment mutex must be
-| reserved, if, e.g., a new page must
-| be added to an undo log. The rollback
-| segment and the undo logs in its
-| history list can be seen as an
-| analogue of a B-tree, and the latches
-| reserved similarly, using a version of
-| lock-coupling. If an undo log must be
-| extended by a page when inserting an
-| undo log record, this corresponds to
-| a pessimistic insert in a B-tree.
-V
-Rollback segment header
-|
-V
-Purge system latch
-|
-V
-Undo log pages If a thread owns the trx undo mutex,
-| or for a log in the history list, the
-| rseg mutex, it is allowed to latch
-| undo log pages in any order, and even
-| after it has acquired the fsp latch.
-| If a thread does not have the
-| appropriate mutex, it is allowed to
-| latch only a single undo log page in
-| a mini-transaction.
-V
-File space management latch If a mini-transaction must allocate
-| several file pages, it can do that,
-| because it keeps the x-latch to the
-| file space management in its memo.
-V
-File system pages
-|
-V
-lock_sys.wait_mutex Mutex protecting lock timeout data
-|
-V
-lock_sys.mutex Mutex protecting lock_sys_t
-|
-V
-trx_sys.mutex Mutex protecting trx_sys.trx_list
-|
-V
-Threads mutex Background thread scheduling mutex
-|
-V
-query_thr_mutex Mutex protecting query threads
-|
-V
-trx_mutex Mutex protecting trx_t fields
-|
-V
-Search system mutex
-|
-V
-Buffer pool mutex
-|
-V
-Log mutex
-|
-Any other latch
-|
-V
-Memory pool mutex */
-
-/** Latching order levels. If you modify these, you have to also update
-LatchDebug internals in sync0debug.cc */
-
-enum latch_level_t {
- SYNC_UNKNOWN = 0,
-
- RW_LOCK_SX,
- RW_LOCK_X_WAIT,
- RW_LOCK_S,
- RW_LOCK_X,
- RW_LOCK_NOT_LOCKED,
-
- SYNC_ANY_LATCH,
-
- SYNC_POOL,
- SYNC_POOL_MANAGER,
-
- SYNC_PURGE_QUEUE,
- SYNC_RW_TRX_HASH_ELEMENT,
- SYNC_READ_VIEW,
- SYNC_TRX_SYS,
-
- SYNC_INDEX_ONLINE_LOG,
-
- SYNC_IBUF_BITMAP_MUTEX,
-
- SYNC_IBUF_MUTEX,
-
- SYNC_NOREDO_RSEG,
- SYNC_REDO_RSEG,
- SYNC_IBUF_PESS_INSERT_MUTEX,
-
- SYNC_STATS_AUTO_RECALC,
- SYNC_DICT,
-
- /** This can be used to suppress order checking. */
- SYNC_NO_ORDER_CHECK,
-
- /** Maximum level value */
- SYNC_LEVEL_MAX = SYNC_NO_ORDER_CHECK
-};
-
-/** Each latch has an ID. This id is used for creating the latch and to look
-up its meta-data. See sync0debug.cc. */
-enum latch_id_t {
- LATCH_ID_NONE = 0,
- LATCH_ID_DICT_FOREIGN_ERR,
- LATCH_ID_DICT_SYS,
- LATCH_ID_FIL_SYSTEM,
- LATCH_ID_IBUF_BITMAP,
- LATCH_ID_IBUF,
- LATCH_ID_IBUF_PESSIMISTIC_INSERT,
- LATCH_ID_PURGE_SYS_PQ,
- LATCH_ID_RECALC_POOL,
- LATCH_ID_REDO_RSEG,
- LATCH_ID_NOREDO_RSEG,
- LATCH_ID_RTR_ACTIVE_MUTEX,
- LATCH_ID_RTR_MATCH_MUTEX,
- LATCH_ID_RTR_PATH_MUTEX,
- LATCH_ID_SRV_INNODB_MONITOR,
- LATCH_ID_SRV_MISC_TMPFILE,
- LATCH_ID_SRV_MONITOR_FILE,
- LATCH_ID_TRX_POOL,
- LATCH_ID_TRX_POOL_MANAGER,
- LATCH_ID_TRX_SYS,
- LATCH_ID_SRV_SYS_TASKS,
- LATCH_ID_PAGE_ZIP_STAT_PER_INDEX,
- LATCH_ID_SYNC_ARRAY_MUTEX,
- LATCH_ID_ROW_DROP_LIST,
- LATCH_ID_INDEX_ONLINE_LOG,
- LATCH_ID_DICT_TABLE_STATS,
- LATCH_ID_DEFRAGMENT_MUTEX,
- LATCH_ID_RW_TRX_HASH_ELEMENT,
- LATCH_ID_READ_VIEW,
- LATCH_ID_MAX = LATCH_ID_READ_VIEW
-};
-
-#ifndef UNIV_INNOCHECKSUM
-/** OS mutex, without any policy. It is a thin wrapper around the
-system mutexes. The interface is different from the policy mutexes,
-to ensure that it is called directly and not confused with the
-policy mutexes. */
-struct OSMutex {
-
- /** Constructor */
- OSMutex()
- UNIV_NOTHROW
- {
- ut_d(m_freed = true);
- }
-
- /** Create the mutex by calling the system functions. */
- void init()
- UNIV_NOTHROW
- {
- ut_ad(m_freed);
-
-#ifdef _WIN32
- InitializeCriticalSection((LPCRITICAL_SECTION) &m_mutex);
-#else
- {
- int ret = pthread_mutex_init(&m_mutex, NULL);
- ut_a(ret == 0);
- }
-#endif /* _WIN32 */
-
- ut_d(m_freed = false);
- }
-
- /** Destructor */
- ~OSMutex() { }
-
- /** Destroy the mutex */
- void destroy()
- UNIV_NOTHROW
- {
- ut_ad(!m_freed);
-#ifdef _WIN32
- DeleteCriticalSection((LPCRITICAL_SECTION) &m_mutex);
-#else
- int ret;
-
- ret = pthread_mutex_destroy(&m_mutex);
-
- if (ret != 0) {
-
- ib::error()
- << "Return value " << ret << " when calling "
- << "pthread_mutex_destroy().";
- }
-#endif /* _WIN32 */
- ut_d(m_freed = true);
- }
-
- /** Release the mutex. */
- void exit()
- UNIV_NOTHROW
- {
- ut_ad(!m_freed);
-#ifdef _WIN32
- LeaveCriticalSection(&m_mutex);
-#else
- int ret = pthread_mutex_unlock(&m_mutex);
- ut_a(ret == 0);
-#endif /* _WIN32 */
- }
-
- /** Acquire the mutex. */
- void enter()
- UNIV_NOTHROW
- {
- ut_ad(!m_freed);
-#ifdef _WIN32
- EnterCriticalSection((LPCRITICAL_SECTION) &m_mutex);
-#else
- int ret = pthread_mutex_lock(&m_mutex);
- ut_a(ret == 0);
-#endif /* _WIN32 */
- }
-
- /** @return true if locking succeeded */
- bool try_lock()
- UNIV_NOTHROW
- {
- ut_ad(!m_freed);
-#ifdef _WIN32
- return(TryEnterCriticalSection(&m_mutex) != 0);
-#else
- return(pthread_mutex_trylock(&m_mutex) == 0);
-#endif /* _WIN32 */
- }
-
- /** Required for os_event_t */
- operator sys_mutex_t*()
- UNIV_NOTHROW
- {
- return(&m_mutex);
- }
-
-private:
-#ifdef DBUG_ASSERT_EXISTS
- /** true if the mutex has been freed/destroyed. */
- bool m_freed;
-#endif /* DBUG_ASSERT_EXISTS */
-
- sys_mutex_t m_mutex;
-};
-
-#ifdef UNIV_PFS_MUTEX
-/** Latch element.
-Used for mutexes which have PFS keys defined under UNIV_PFS_MUTEX.
-@param[in] id Latch id
-@param[in] level Latch level
-@param[in] key PFS key */
-# define LATCH_ADD_MUTEX(id, level, key) latch_meta[LATCH_ID_ ## id] =\
- UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, key))
-
-#ifdef UNIV_PFS_RWLOCK
-/** Latch element.
-Used for rwlocks which have PFS keys defined under UNIV_PFS_RWLOCK.
-@param[in] id Latch id
-@param[in] level Latch level
-@param[in] key PFS key */
-# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\
- UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, key))
-#else
-# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\
- UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level, \
- PSI_NOT_INSTRUMENTED))
-#endif /* UNIV_PFS_RWLOCK */
-
-#else
-# define LATCH_ADD_MUTEX(id, level, key) latch_meta[LATCH_ID_ ## id] =\
- UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level))
-# define LATCH_ADD_RWLOCK(id, level, key) latch_meta[LATCH_ID_ ## id] =\
- UT_NEW_NOKEY(latch_meta_t(LATCH_ID_ ## id, #id, level, #level))
-#endif /* UNIV_PFS_MUTEX */
-
-/** Default latch counter */
-class LatchCounter {
-
-public:
- /** The counts we collect for a mutex */
- struct Count {
-
- /** Constructor */
- Count()
- UNIV_NOTHROW
- :
- m_spins(),
- m_waits(),
- m_calls(),
- m_enabled()
- {
- /* No op */
- }
-
- /** Rest the values to zero */
- void reset()
- UNIV_NOTHROW
- {
- m_spins = 0;
- m_waits = 0;
- m_calls = 0;
- }
-
- /** Number of spins trying to acquire the latch. */
- uint32_t m_spins;
-
- /** Number of waits trying to acquire the latch */
- uint32_t m_waits;
-
- /** Number of times it was called */
- uint32_t m_calls;
-
- /** true if enabled */
- bool m_enabled;
- };
-
- /** Constructor */
- LatchCounter()
- UNIV_NOTHROW
- :
- m_active(false)
- {
- m_mutex.init();
- }
-
- /** Destructor */
- ~LatchCounter()
- UNIV_NOTHROW
- {
- m_mutex.destroy();
-
- for (Counters::iterator it = m_counters.begin();
- it != m_counters.end();
- ++it) {
-
- Count* count = *it;
-
- UT_DELETE(count);
- }
- }
-
- /** Reset all counters to zero. It is not protected by any
- mutex and we don't care about atomicity. Unless it is a
- demonstrated problem. The information collected is not
- required for the correct functioning of the server. */
- void reset()
- UNIV_NOTHROW
- {
- m_mutex.enter();
-
- Counters::iterator end = m_counters.end();
-
- for (Counters::iterator it = m_counters.begin();
- it != end;
- ++it) {
-
- (*it)->reset();
- }
-
- m_mutex.exit();
- }
-
- /** @return the aggregate counter */
- Count* sum_register()
- UNIV_NOTHROW
- {
- m_mutex.enter();
-
- Count* count;
-
- if (m_counters.empty()) {
- count = UT_NEW_NOKEY(Count());
- m_counters.push_back(count);
- } else {
- ut_a(m_counters.size() == 1);
- count = m_counters[0];
- }
-
- m_mutex.exit();
-
- return(count);
- }
-
- /** Register a single instance counter */
- void single_register(Count* count)
- UNIV_NOTHROW
- {
- m_mutex.enter();
-
- m_counters.push_back(count);
-
- m_mutex.exit();
- }
-
- /** Deregister a single instance counter
- @param[in] count The count instance to deregister */
- void single_deregister(Count* count)
- UNIV_NOTHROW
- {
- m_mutex.enter();
-
- m_counters.erase(
- std::remove(
- m_counters.begin(),
- m_counters.end(), count),
- m_counters.end());
-
- m_mutex.exit();
- }
-
- /** Iterate over the counters */
- template<typename C> void iterate(const C& callback) UNIV_NOTHROW
- {
- m_mutex.enter();
-
- Counters::const_iterator end = m_counters.end();
-
- for (Counters::const_iterator it = m_counters.begin();
- it != end;
- ++it) {
-
- callback(*it);
- }
-
- m_mutex.exit();
- }
-
- /** Disable the monitoring */
- void enable()
- UNIV_NOTHROW
- {
- m_mutex.enter();
-
- Counters::const_iterator end = m_counters.end();
-
- for (Counters::const_iterator it = m_counters.begin();
- it != end;
- ++it) {
-
- (*it)->m_enabled = true;
- }
-
- m_active = true;
-
- m_mutex.exit();
- }
-
- /** Disable the monitoring */
- void disable()
- UNIV_NOTHROW
- {
- m_mutex.enter();
-
- Counters::const_iterator end = m_counters.end();
-
- for (Counters::const_iterator it = m_counters.begin();
- it != end;
- ++it) {
-
- (*it)->m_enabled = false;
- }
-
- m_active = false;
-
- m_mutex.exit();
- }
-
- /** @return if monitoring is active */
- bool is_enabled() const
- UNIV_NOTHROW
- {
- return(m_active);
- }
-
-private:
- /* Disable copying */
- LatchCounter(const LatchCounter&);
- LatchCounter& operator=(const LatchCounter&);
-
-private:
- typedef OSMutex Mutex;
- typedef std::vector<Count*> Counters;
-
- /** Mutex protecting m_counters */
- Mutex m_mutex;
-
- /** Counters for the latches */
- Counters m_counters;
-
- /** if true then we collect the data */
- bool m_active;
-};
-
-/** Latch meta data */
-template <typename Counter = LatchCounter>
-class LatchMeta {
-
-public:
- typedef Counter CounterType;
-
-#ifdef UNIV_PFS_MUTEX
- typedef mysql_pfs_key_t pfs_key_t;
-#endif /* UNIV_PFS_MUTEX */
-
- /** Constructor */
- LatchMeta()
- :
- m_id(LATCH_ID_NONE),
- m_name(),
- m_level(SYNC_UNKNOWN),
- m_level_name()
-#ifdef UNIV_PFS_MUTEX
- ,m_pfs_key()
-#endif /* UNIV_PFS_MUTEX */
- {
- }
-
- /** Destructor */
- ~LatchMeta() { }
-
- /** Constructor
- @param[in] id Latch id
- @param[in] name Latch name
- @param[in] level Latch level
- @param[in] level_name Latch level text representation
- @param[in] key PFS key */
- LatchMeta(
- latch_id_t id,
- const char* name,
- latch_level_t level,
- const char* level_name
-#ifdef UNIV_PFS_MUTEX
- ,pfs_key_t key
-#endif /* UNIV_PFS_MUTEX */
- )
- :
- m_id(id),
- m_name(name),
- m_level(level),
- m_level_name(level_name)
-#ifdef UNIV_PFS_MUTEX
- ,m_pfs_key(key)
-#endif /* UNIV_PFS_MUTEX */
- {
- /* No op */
- }
-
- /* Less than operator.
- @param[in] rhs Instance to compare against
- @return true if this.get_id() < rhs.get_id() */
- bool operator<(const LatchMeta& rhs) const
- {
- return(get_id() < rhs.get_id());
- }
-
- /** @return the latch id */
- latch_id_t get_id() const
- {
- return(m_id);
- }
-
- /** @return the latch name */
- const char* get_name() const
- {
- return(m_name);
- }
-
- /** @return the latch level */
- latch_level_t get_level() const
- {
- return(m_level);
- }
-
- /** @return the latch level name */
- const char* get_level_name() const
- {
- return(m_level_name);
- }
-
-#ifdef UNIV_PFS_MUTEX
- /** @return the PFS key for the latch */
- pfs_key_t get_pfs_key() const
- {
- return(m_pfs_key);
- }
-#endif /* UNIV_PFS_MUTEX */
-
- /** @return the counter instance */
- Counter* get_counter()
- {
- return(&m_counter);
- }
-
-private:
- /** Latch id */
- latch_id_t m_id;
-
- /** Latch name */
- const char* m_name;
-
- /** Latch level in the ordering */
- latch_level_t m_level;
-
- /** Latch level text representation */
- const char* m_level_name;
-
-#ifdef UNIV_PFS_MUTEX
- /** PFS key */
- pfs_key_t m_pfs_key;
-#endif /* UNIV_PFS_MUTEX */
-
- /** For gathering latch statistics */
- Counter m_counter;
-};
-
-typedef LatchMeta<LatchCounter> latch_meta_t;
-typedef std::vector<latch_meta_t*, ut_allocator<latch_meta_t*> > LatchMetaData;
-
-/** Note: This is accessed without any mutex protection. It is initialised
-at startup and elements should not be added to or removed from it after
-that. See sync_latch_meta_init() */
-extern LatchMetaData latch_meta;
-
-/** Get the latch meta-data from the latch ID
-@param[in] id Latch ID
-@return the latch meta data */
-inline
-latch_meta_t&
-sync_latch_get_meta(latch_id_t id)
-{
- ut_ad(static_cast<size_t>(id) < latch_meta.size());
- ut_ad(id == latch_meta[id]->get_id());
-
- return(*latch_meta[id]);
-}
-
-/** Fetch the counter for the latch
-@param[in] id Latch ID
-@return the latch counter */
-inline
-latch_meta_t::CounterType*
-sync_latch_get_counter(latch_id_t id)
-{
- latch_meta_t& meta = sync_latch_get_meta(id);
-
- return(meta.get_counter());
-}
-
-/** Get the latch name from the latch ID
-@param[in] id Latch ID
-@return the name, will assert if not found */
-inline
-const char*
-sync_latch_get_name(latch_id_t id)
-{
- const latch_meta_t& meta = sync_latch_get_meta(id);
-
- return(meta.get_name());
-}
-
-/** Get the latch ordering level
-@param[in] id Latch id to lookup
-@return the latch level */
-inline
-latch_level_t
-sync_latch_get_level(latch_id_t id)
-{
- const latch_meta_t& meta = sync_latch_get_meta(id);
-
- return(meta.get_level());
-}
-
-#ifdef UNIV_PFS_MUTEX
-/** Get the latch PFS key from the latch ID
-@param[in] id Latch ID
-@return the PFS key */
-inline
-mysql_pfs_key_t
-sync_latch_get_pfs_key(latch_id_t id)
-{
- const latch_meta_t& meta = sync_latch_get_meta(id);
-
- return(meta.get_pfs_key());
-}
-#endif
-
-/** String representation of the filename and line number where the
-latch was created
-@param[in] id Latch ID
-@param[in] created Filename and line number where it was crated
-@return the string representation */
-std::string
-sync_mutex_to_string(
- latch_id_t id,
- const std::string& created);
-
-/** Get the latch name from a sync level
-@param[in] level Latch level to lookup
-@return 0 if not found. */
-const char*
-sync_latch_get_name(latch_level_t level);
-
-/** Print the filename "basename"
-@return the basename */
-const char*
-sync_basename(const char* filename);
-
-#ifdef UNIV_DEBUG
-
-/** All (ordered) latches, used in debugging, must derive from this class. */
-struct latch_t {
-
- /** Constructor
- @param[in] id The latch ID */
- explicit latch_t(latch_id_t id = LATCH_ID_NONE)
- UNIV_NOTHROW
- : m_id(id) {}
-
- /** Destructor */
- virtual ~latch_t() UNIV_NOTHROW { }
-
- /** @return the latch ID */
- latch_id_t get_id() const
- {
- return(m_id);
- }
-
- /** Print the latch context
- @return the string representation */
- virtual std::string to_string() const = 0;
-
- /** @return the latch level */
- latch_level_t get_level() const
- UNIV_NOTHROW
- {
- ut_a(m_id != LATCH_ID_NONE);
-
- return(sync_latch_get_level(m_id));
- }
-
- /** @return the latch name, m_id must be set */
- const char* get_name() const
- UNIV_NOTHROW
- {
- ut_a(m_id != LATCH_ID_NONE);
-
- return(sync_latch_get_name(m_id));
- }
-
- /** Latch ID */
- latch_id_t m_id;
-};
-
-/** Subclass this to iterate over a thread's acquired latch levels. */
-struct sync_check_functor_t {
- virtual ~sync_check_functor_t() { }
- virtual bool operator()(const latch_level_t) const = 0;
-};
-
-/** Check that no latch is being held.
-@tparam some_allowed whether some latches are allowed to be held */
-template<bool some_allowed = false>
-struct sync_checker : public sync_check_functor_t
-{
- /** Check the latching constraints
- @param[in] level The level held by the thread
- @return whether a latch violation was detected */
- bool operator()(const latch_level_t level) const override
- {
- if (some_allowed) {
- switch (level) {
- case SYNC_DICT:
- case SYNC_NO_ORDER_CHECK:
- return(false);
- default:
- return(true);
- }
- }
-
- return(true);
- }
-};
-
-/** The strict latch checker (no InnoDB latches may be held) */
-typedef struct sync_checker<false> sync_check;
-/** The sloppy latch checker (can hold InnoDB dictionary or SQL latches) */
-typedef struct sync_checker<true> dict_sync_check;
-
-/** Functor to check for given latching constraints. */
-struct sync_allowed_latches : public sync_check_functor_t {
-
- /** Constructor
- @param[in] from first element in an array of latch_level_t
- @param[in] to last element in an array of latch_level_t */
- sync_allowed_latches(
- const latch_level_t* from,
- const latch_level_t* to)
- : begin(from), end(to) { }
-
- /** Checks whether the given latch_t violates the latch constraint.
- This object maintains a list of allowed latch levels, and if the given
- latch belongs to a latch level that is not there in the allowed list,
- then it is a violation.
-
- @param[in] latch The latch level to check
- @return true if there is a latch violation */
- bool operator()(const latch_level_t level) const override
- {
- return(std::find(begin, end, level) == end);
- }
-
-private:
- /** First element in an array of allowed latch levels */
- const latch_level_t* const begin;
- /** First element after the end of the array of allowed latch levels */
- const latch_level_t* const end;
-};
-
-/** Get the latch id from a latch name.
-@param[in] id Latch name
-@return LATCH_ID_NONE. */
-latch_id_t
-sync_latch_get_id(const char* name);
-#endif /* UNIV_DBEUG */
-
-#endif /* UNIV_INNOCHECKSUM */
-
-/** Simple non-atomic counter aligned to CACHE_LINE_SIZE
-@tparam Type the integer type of the counter */
-template <typename Type>
-struct MY_ALIGNED(CPU_LEVEL1_DCACHE_LINESIZE) simple_counter
-{
- /** Increment the counter */
- Type inc() { return add(1); }
- /** Decrement the counter */
- Type dec() { return add(Type(~0)); }
-
- /** Add to the counter
- @param[in] i amount to be added
- @return the value of the counter after adding */
- Type add(Type i) { return m_counter += i; }
-
- /** @return the value of the counter */
- operator Type() const { return m_counter; }
-
-private:
- /** The counter */
- Type m_counter;
-};
-#endif /* sync0types_h */
diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h
index 7af880ef21e..fd9ccfd386e 100644
--- a/storage/innobase/include/trx0purge.h
+++ b/storage/innobase/include/trx0purge.h
@@ -190,7 +190,7 @@ public:
purge_pq_t purge_queue; /*!< Binary min-heap, ordered on
TrxUndoRsegs::trx_no. It is protected
by the pq_mutex */
- PQMutex pq_mutex; /*!< Mutex protecting purge_queue */
+ mysql_mutex_t pq_mutex; /*!< Mutex protecting purge_queue */
/** Undo tablespace file truncation (only accessed by the
srv_purge_coordinator_thread) */
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index a3ccc90b630..a42c1a0433a 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -30,6 +30,11 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0sys.h"
#include "fut0lst.h"
+#ifdef UNIV_PFS_MUTEX
+extern mysql_pfs_key_t redo_rseg_mutex_key;
+extern mysql_pfs_key_t noredo_rseg_mutex_key;
+#endif /* UNIV_PFS_MUTEX */
+
/** Gets a rollback segment header.
@param[in] space space where placed
@param[in] page_no page number of the header
@@ -100,7 +105,7 @@ struct trx_rseg_t {
/** mutex protecting the fields in this struct except id,space,page_no
which are constant */
- RsegMutex mutex;
+ mysql_mutex_t mutex;
/** space where the rollback segment header is placed */
fil_space_t* space;
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index d9707eae4ae..f99ef4eb7ce 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -24,9 +24,7 @@ Transaction system
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-#ifndef trx0sys_h
-#define trx0sys_h
-
+#pragma once
#include "buf0buf.h"
#include "fil0fil.h"
#include "trx0types.h"
@@ -36,12 +34,17 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0lst.h"
#include "read0types.h"
#include "page0types.h"
-#include "ut0mutex.h"
#include "trx0trx.h"
#ifdef WITH_WSREP
#include "trx0xa.h"
#endif /* WITH_WSREP */
#include "ilist.h"
+#include "my_cpu.h"
+
+#ifdef UNIV_PFS_MUTEX
+extern mysql_pfs_key_t trx_sys_mutex_key;
+extern mysql_pfs_key_t rw_trx_hash_element_mutex_key;
+#endif
/** Checks if a page address is the trx sys header page.
@param[in] page_id page id
@@ -345,13 +348,13 @@ struct rw_trx_hash_element_t
{
rw_trx_hash_element_t(): trx(0)
{
- mutex_create(LATCH_ID_RW_TRX_HASH_ELEMENT, &mutex);
+ mysql_mutex_init(rw_trx_hash_element_mutex_key, &mutex, nullptr);
}
~rw_trx_hash_element_t()
{
- mutex_free(&mutex);
+ mysql_mutex_destroy(&mutex);
}
@@ -365,7 +368,7 @@ struct rw_trx_hash_element_t
*/
Atomic_counter<trx_id_t> no;
trx_t *trx;
- ib_mutex_t mutex;
+ mysql_mutex_t mutex;
};
@@ -534,10 +537,10 @@ class rw_trx_hash_t
static my_bool debug_iterator(rw_trx_hash_element_t *element,
debug_iterator_arg<T> *arg)
{
- mutex_enter(&element->mutex);
+ mysql_mutex_lock(&element->mutex);
if (element->trx)
validate_element(element->trx);
- mutex_exit(&element->mutex);
+ mysql_mutex_unlock(&element->mutex);
return arg->action(element, arg->argument);
}
#endif
@@ -639,7 +642,7 @@ public:
sizeof(trx_id_t)));
if (element)
{
- mutex_enter(&element->mutex);
+ mysql_mutex_lock(&element->mutex);
lf_hash_search_unpin(pins);
if ((trx= element->trx)) {
DBUG_ASSERT(trx_id == trx->id);
@@ -660,7 +663,7 @@ public:
trx->reference();
}
}
- mutex_exit(&element->mutex);
+ mysql_mutex_unlock(&element->mutex);
}
if (!caller_trx)
lf_hash_put_pins(pins);
@@ -694,9 +697,9 @@ public:
void erase(trx_t *trx)
{
ut_d(validate_element(trx));
- mutex_enter(&trx->rw_trx_hash_element->mutex);
+ mysql_mutex_lock(&trx->rw_trx_hash_element->mutex);
trx->rw_trx_hash_element->trx= 0;
- mutex_exit(&trx->rw_trx_hash_element->mutex);
+ mysql_mutex_unlock(&trx->rw_trx_hash_element->mutex);
int res= lf_hash_delete(&hash, get_pins(trx),
reinterpret_cast<const void*>(&trx->id),
sizeof(trx_id_t));
@@ -730,12 +733,12 @@ public:
May return element with committed transaction. If caller doesn't like to
see committed transactions, it has to skip those under element mutex:
- mutex_enter(&element->mutex);
+ mysql_mutex_lock(&element->mutex);
if (trx_t trx= element->trx)
{
// trx is protected against commit in this branch
}
- mutex_exit(&element->mutex);
+ mysql_mutex_unlock(&element->mutex);
May miss concurrently inserted transactions.
@@ -796,44 +799,44 @@ public:
class thread_safe_trx_ilist_t
{
public:
- void create() { mutex_create(LATCH_ID_TRX_SYS, &mutex); }
- void close() { mutex_free(&mutex); }
+ void create() { mysql_mutex_init(trx_sys_mutex_key, &mutex, nullptr); }
+ void close() { mysql_mutex_destroy(&mutex); }
bool empty() const
{
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
auto result= trx_list.empty();
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
return result;
}
void push_front(trx_t &trx)
{
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
trx_list.push_front(trx);
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
}
void remove(trx_t &trx)
{
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
trx_list.remove(trx);
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
}
template <typename Callable> void for_each(Callable &&callback) const
{
- mutex_enter(&mutex);
+ mysql_mutex_lock(&mutex);
for (const auto &trx : trx_list)
callback(trx);
- mutex_exit(&mutex);
+ mysql_mutex_unlock(&mutex);
}
- void freeze() const { mutex_enter(&mutex); }
- void unfreeze() const { mutex_exit(&mutex); }
+ void freeze() const { mysql_mutex_lock(&mutex); }
+ void unfreeze() const { mysql_mutex_unlock(&mutex); }
private:
- alignas(CACHE_LINE_SIZE) mutable TrxSysMutex mutex;
+ alignas(CACHE_LINE_SIZE) mutable mysql_mutex_t mutex;
alignas(CACHE_LINE_SIZE) ilist<trx_t> trx_list;
};
@@ -1148,11 +1151,11 @@ private:
{
if (element->id < *id)
{
- mutex_enter(&element->mutex);
+ mysql_mutex_lock(&element->mutex);
/* We don't care about read-only transactions here. */
if (element->trx && element->trx->rsegs.m_redo.rseg)
*id= element->id;
- mutex_exit(&element->mutex);
+ mysql_mutex_unlock(&element->mutex);
}
return 0;
}
@@ -1217,5 +1220,3 @@ private:
/** The transaction system */
extern trx_sys_t trx_sys;
-
-#endif
diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h
index 24e07e7ebbf..aa5293ca996 100644
--- a/storage/innobase/include/trx0types.h
+++ b/storage/innobase/include/trx0types.h
@@ -24,11 +24,9 @@ Transaction system global type definitions
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-#ifndef trx0types_h
-#define trx0types_h
-
-#include "ut0byte.h"
-#include "ut0mutex.h"
+#pragma once
+#include "univ.i"
+#include "ut0new.h"
#include <vector>
@@ -135,9 +133,4 @@ typedef byte trx_undo_rec_t;
/* @} */
-typedef ib_mutex_t RsegMutex;
-typedef ib_mutex_t PQMutex;
-typedef ib_mutex_t TrxSysMutex;
-
typedef std::vector<trx_id_t, ut_allocator<trx_id_t> > trx_ids_t;
-#endif /* trx0types_h */
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 18c228e56c3..2091bd70500 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -31,8 +31,7 @@ Version control for database, common definitions, and include files
Created 1/20/1994 Heikki Tuuri
****************************************************************************/
-#ifndef univ_i
-#define univ_i
+#pragma once
/* aux macros to convert M into "123" (string) if M is defined like
#define M 123 */
@@ -194,8 +193,6 @@ using the call command. */
related stuff. */
#define UNIV_SEARCH_PERF_STAT /* statistics for the
adaptive hash index */
-#define UNIV_SRV_PRINT_LATCH_WAITS /* enable diagnostic output
- in sync0sync.cc */
#define UNIV_BTR_PRINT /* enable functions for
printing B-trees */
#define UNIV_ZIP_DEBUG /* extensive consistency checks
@@ -563,7 +560,6 @@ typedef void* os_thread_ret_t;
#include "ut0dbg.h"
#include "ut0lst.h"
#include "ut0ut.h"
-#include "sync0types.h"
extern ulong srv_page_size_shift;
extern ulong srv_page_size;
@@ -572,4 +568,53 @@ extern ulong srv_page_size;
myisam/sp_defs.h. We only support 2 dimension data */
#define SPDIMS 2
-#endif
+#ifdef HAVE_PSI_INTERFACE
+typedef unsigned int mysql_pfs_key_t;
+
+# ifdef UNIV_PFS_MUTEX
+extern mysql_pfs_key_t buf_pool_mutex_key;
+extern mysql_pfs_key_t dict_foreign_err_mutex_key;
+extern mysql_pfs_key_t dict_sys_mutex_key;
+extern mysql_pfs_key_t fil_system_mutex_key;
+extern mysql_pfs_key_t flush_list_mutex_key;
+extern mysql_pfs_key_t fts_cache_mutex_key;
+extern mysql_pfs_key_t fts_cache_init_mutex_key;
+extern mysql_pfs_key_t fts_delete_mutex_key;
+extern mysql_pfs_key_t fts_doc_id_mutex_key;
+extern mysql_pfs_key_t fts_pll_tokenize_mutex_key;
+extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
+extern mysql_pfs_key_t ibuf_mutex_key;
+extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
+extern mysql_pfs_key_t log_sys_mutex_key;
+extern mysql_pfs_key_t log_cmdq_mutex_key;
+extern mysql_pfs_key_t log_flush_order_mutex_key;
+extern mysql_pfs_key_t recalc_pool_mutex_key;
+extern mysql_pfs_key_t purge_sys_pq_mutex_key;
+extern mysql_pfs_key_t recv_sys_mutex_key;
+extern mysql_pfs_key_t rtr_active_mutex_key;
+extern mysql_pfs_key_t rtr_match_mutex_key;
+extern mysql_pfs_key_t rtr_path_mutex_key;
+extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key;
+extern mysql_pfs_key_t srv_innodb_monitor_mutex_key;
+extern mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
+extern mysql_pfs_key_t srv_monitor_file_mutex_key;
+extern mysql_pfs_key_t buf_dblwr_mutex_key;
+extern mysql_pfs_key_t trx_pool_mutex_key;
+extern mysql_pfs_key_t trx_pool_manager_mutex_key;
+extern mysql_pfs_key_t lock_mutex_key;
+extern mysql_pfs_key_t lock_wait_mutex_key;
+extern mysql_pfs_key_t srv_threads_mutex_key;
+extern mysql_pfs_key_t thread_mutex_key;
+extern mysql_pfs_key_t row_drop_list_mutex_key;
+# endif /* UNIV_PFS_MUTEX */
+
+# ifdef UNIV_PFS_RWLOCK
+extern mysql_pfs_key_t dict_operation_lock_key;
+extern mysql_pfs_key_t fil_space_latch_key;
+extern mysql_pfs_key_t trx_i_s_cache_lock_key;
+extern mysql_pfs_key_t trx_purge_latch_key;
+extern mysql_pfs_key_t index_tree_rw_lock_key;
+extern mysql_pfs_key_t index_online_log_key;
+extern mysql_pfs_key_t trx_sys_rw_lock_key;
+# endif /* UNIV_PFS_RWLOCK */
+#endif /* HAVE_PSI_INTERFACE */
diff --git a/storage/innobase/include/ut0mutex.h b/storage/innobase/include/ut0mutex.h
deleted file mode 100644
index 89c903b48f1..00000000000
--- a/storage/innobase/include/ut0mutex.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*****************************************************************************
-
-Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; version 2 of the License.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
-
-*****************************************************************************/
-
-/******************************************************************//**
-@file include/ut0mutex.h
-Policy based mutexes.
-
-Created 2012-03-24 Sunny Bains.
-***********************************************************************/
-
-#pragma once
-#ifndef UNIV_INNOCHECKSUM
-#include "sync0policy.h"
-#include "ib0mutex.h"
-
-/** Create a typedef using the MutexType<PolicyType>
-@param[in] M Mutex type
-@param[in[ P Policy type
-@param[in] T The resulting typedef alias */
-#define UT_MUTEX_TYPE(M, P, T) typedef PolicyMutex<M<P> > T;
-
-# ifdef __linux__
-UT_MUTEX_TYPE(TTASFutexMutex, GenericPolicy, FutexMutex);
-# endif /* __linux__ */
-
-UT_MUTEX_TYPE(TTASMutex, GenericPolicy, SpinMutex);
-UT_MUTEX_TYPE(OSTrackMutex, GenericPolicy, SysMutex);
-
-#ifdef MUTEX_FUTEX
-/** The default mutex type. */
-typedef FutexMutex ib_mutex_t;
-#define MUTEX_TYPE "Uses futexes"
-#elif defined(MUTEX_SYS)
-typedef SysMutex ib_mutex_t;
-#define MUTEX_TYPE "Uses system mutexes"
-#else
-#error "ib_mutex_t type is unknown"
-#endif /* MUTEX_FUTEX */
-
-extern uint srv_spin_wait_delay;
-extern ulong srv_n_spin_wait_rounds;
-
-#define mutex_create(I, M) mutex_init((M), (I), \
- __FILE__, __LINE__)
-
-#define mutex_enter_loc(M,file,line) (M)->enter( \
- uint32_t(srv_n_spin_wait_rounds), \
- uint32_t(srv_spin_wait_delay), \
- file, line)
-#define mutex_enter(M) mutex_enter_loc(M, __FILE__, __LINE__)
-
-#define mutex_enter_nospin(M) (M)->enter( \
- 0, \
- 0, \
- __FILE__, uint32_t(__LINE__))
-
-#define mutex_enter_nowait(M) (M)->trylock(__FILE__, \
- uint32_t(__LINE__))
-
-#define mutex_exit(M) (M)->exit()
-
-#define mutex_free(M) mutex_destroy(M)
-
-#ifdef UNIV_DEBUG
-/**
-Checks that the mutex has been initialized. */
-#define mutex_validate(M) (M)->validate()
-
-/**
-Checks that the current thread owns the mutex. Works only
-in the debug version. */
-#define mutex_own(M) (M)->is_owned()
-#else
-#define mutex_own(M) /* No op */
-#define mutex_validate(M) /* No op */
-#endif /* UNIV_DEBUG */
-
-/** Iterate over the mutex meta data */
-class MutexMonitor {
-public:
- /** Constructor */
- MutexMonitor() { }
-
- /** Destructor */
- ~MutexMonitor() { }
-
- /** Enable the mutex monitoring */
- void enable();
-
- /** Disable the mutex monitoring */
- void disable();
-
- /** Reset the mutex monitoring values */
- void reset();
-
- /** Invoke the callback for each active mutex collection
- @param[in,out] callback Functor to call
- @return false if callback returned false */
- template<typename Callback>
- bool iterate(Callback& callback) const
- UNIV_NOTHROW
- {
- LatchMetaData::iterator end = latch_meta.end();
-
- for (LatchMetaData::iterator it = latch_meta.begin();
- it != end;
- ++it) {
-
- /* Some of the slots will be null in non-debug mode */
-
- if (latch_meta_t* l= *it) {
- if (!callback(*l)) {
- return false;
- }
- }
- }
-
- return(true);
- }
-};
-
-/** Defined in sync0sync.cc */
-extern MutexMonitor mutex_monitor;
-
-/**
-Creates, or rather, initializes a mutex object in a specified memory
-location (which must be appropriately aligned). The mutex is initialized
-in the reset state. Explicit freeing of the mutex with mutex_free is
-necessary only if the memory block containing it is freed.
-Add the mutex instance to the global mutex list.
-@param[in,out] mutex mutex to initialise
-@param[in] id The mutex ID (Latch ID)
-@param[in] filename Filename from where it was called
-@param[in] line Line number in filename from where called */
-template <typename Mutex>
-void mutex_init(
- Mutex* mutex,
- latch_id_t id,
- const char* file_name,
- uint32_t line)
-{
- new(mutex) Mutex();
-
- mutex->init(id, file_name, line);
-}
-
-/**
-Removes a mutex instance from the mutex list. The mutex is checked to
-be in the reset state.
-@param[in,out] mutex mutex instance to destroy */
-template <typename Mutex>
-void mutex_destroy(
- Mutex* mutex)
-{
- mutex->destroy();
-}
-
-#endif /* UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h
index 3fc7664c34e..47198dbff99 100644
--- a/storage/innobase/include/ut0new.h
+++ b/storage/innobase/include/ut0new.h
@@ -878,9 +878,6 @@ constexpr const char* const auto_event_names[] =
"row0mysql",
"row0sel",
"srv0start",
- "sync0debug",
- "sync0start",
- "sync0types",
"trx0i_s",
"trx0i_s",
"trx0roll",
diff --git a/storage/innobase/include/ut0wqueue.h b/storage/innobase/include/ut0wqueue.h
index 5c9fd98ea9c..dff8183b6c9 100644
--- a/storage/innobase/include/ut0wqueue.h
+++ b/storage/innobase/include/ut0wqueue.h
@@ -33,7 +33,6 @@ processing.
#pragma once
#include "ut0list.h"
-#include "ut0mutex.h"
#include "mem0mem.h"
// Forward declaration