summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-07-22 16:17:53 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-07-23 08:28:17 +0300
commit5f2628d1eea21d9732f582b77782b072e5e04014 (patch)
treece8ad509e242d4acc5bd4e050acaf027a3d1c73f
parentddb8309e8c1bac8d419fe5c224665c6dca1e2878 (diff)
downloadmariadb-git-5f2628d1eea21d9732f582b77782b072e5e04014.tar.gz
MDEV-22778 Slow InnoDB shutdown on large instance
Starting with MDEV-17441 we would no longer have os_once, and we would always initialize zip_pad_info_t::mutex and dict_table_t::autoinc_mutex, even for tables are not in ROW_FORMAT=COMPRESSED nor include any AUTO_INCREMENT column. mutex_free() on those unnecessary objects would make shutdown very slow compared to older versions. Let us use std::mutex for those two mutexes, to reduce the overhead. The critical sections protected by these mutexes is very small, and therefore contention or the need for any instrumentation should be unlikely.
-rw-r--r--storage/innobase/dict/dict0dict.cc14
-rw-r--r--storage/innobase/dict/dict0mem.cc4
-rw-r--r--storage/innobase/handler/ha_innodb.cc49
-rw-r--r--storage/innobase/include/dict0dict.h4
-rw-r--r--storage/innobase/include/dict0mem.h7
-rw-r--r--storage/innobase/include/sync0sync.h2
-rw-r--r--storage/innobase/include/sync0types.h3
-rw-r--r--storage/innobase/page/page0zip.cc2
-rw-r--r--storage/innobase/sync/sync0debug.cc6
-rw-r--r--storage/innobase/sync/sync0sync.cc3
10 files changed, 36 insertions, 58 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 07fcd4f57c1..3bf701b556a 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -985,7 +985,7 @@ inline void dict_sys_t::add(dict_table_t* table)
ulint fold = ut_fold_string(table->name.m_name);
- mutex_create(LATCH_ID_AUTOINC, &table->autoinc_mutex);
+ new (&table->autoinc_mutex) std::mutex();
/* Look for a table with the same name: error if such exists */
{
@@ -1115,7 +1115,7 @@ dict_index_t *dict_index_t::clone() const
(mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_sample_sizes));
index->stat_n_non_null_key_vals= static_cast<ib_uint64_t*>
(mem_heap_zalloc(heap, n_uniq * sizeof *stat_n_non_null_key_vals));
- mutex_create(LATCH_ID_ZIP_PAD_MUTEX, &index->zip_pad.mutex);
+ new (&index->zip_pad.mutex) std::mutex();
return index;
}
@@ -1777,7 +1777,7 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
UT_DELETE(table->vc_templ);
}
- mutex_free(&table->autoinc_mutex);
+ table->autoinc_mutex.~mutex();
if (keep) {
return;
@@ -6200,10 +6200,10 @@ dict_index_zip_success(
return;
}
- mutex_enter(&index->zip_pad.mutex);
+ index->zip_pad.mutex.lock();
++index->zip_pad.success;
dict_index_zip_pad_update(&index->zip_pad, zip_threshold);
- mutex_exit(&index->zip_pad.mutex);
+ index->zip_pad.mutex.unlock();
}
/*********************************************************************//**
@@ -6220,10 +6220,10 @@ dict_index_zip_failure(
return;
}
- mutex_enter(&index->zip_pad.mutex);
+ index->zip_pad.mutex.lock();
++index->zip_pad.failure;
dict_index_zip_pad_update(&index->zip_pad, zip_threshold);
- mutex_exit(&index->zip_pad.mutex);
+ index->zip_pad.mutex.unlock();
}
/*********************************************************************//**
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index bbc5535668c..e9e0d33bf9f 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -789,7 +789,7 @@ dict_mem_index_create(
dict_mem_fill_index_struct(index, heap, index_name, type, n_fields);
- mutex_create(LATCH_ID_ZIP_PAD_MUTEX, &index->zip_pad.mutex);
+ new (&index->zip_pad.mutex) std::mutex();
if (type & DICT_SPATIAL) {
index->rtr_track = new
@@ -1098,7 +1098,7 @@ dict_mem_index_free(
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
- mutex_free(&index->zip_pad.mutex);
+ index->zip_pad.mutex.~mutex();
if (dict_index_is_spatial(index)) {
for (auto& rtr_info : index->rtr_track->rtr_active) {
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index aaadcb94946..9678c466cb4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -582,7 +582,6 @@ static PSI_cond_info all_innodb_conds[] = {
performance schema instrumented if "UNIV_PFS_MUTEX"
is defined */
static PSI_mutex_info all_innodb_mutexes[] = {
- PSI_KEY(autoinc_mutex),
# ifndef PFS_SKIP_BUFFER_MUTEX_RWLOCK
PSI_KEY(buffer_block_mutex),
# endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
@@ -635,7 +634,6 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(rtr_match_mutex),
PSI_KEY(rtr_path_mutex),
PSI_KEY(trx_sys_mutex),
- PSI_KEY(zip_pad_mutex)
};
# endif /* UNIV_PFS_MUTEX */
@@ -2587,7 +2585,7 @@ ha_innobase::innobase_reset_autoinc(
if (error == DB_SUCCESS) {
dict_table_autoinc_initialize(m_prebuilt->table, autoinc);
- mutex_exit(&m_prebuilt->table->autoinc_mutex);
+ m_prebuilt->table->autoinc_mutex.unlock();
}
return(error);
@@ -6016,7 +6014,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
const unsigned col_no = innodb_col_no(field);
- mutex_enter(&table->autoinc_mutex);
+ table->autoinc_mutex.lock();
table->persistent_autoinc = 1
+ dict_table_get_nth_col_pos(table, col_no, NULL);
@@ -6046,7 +6044,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
innobase_get_int_col_max_value(field));
}
- mutex_exit(&table->autoinc_mutex);
+ table->autoinc_mutex.unlock();
}
/** Open an InnoDB table
@@ -7867,7 +7865,7 @@ ha_innobase::innobase_lock_autoinc(void)
switch (innobase_autoinc_lock_mode) {
case AUTOINC_NO_LOCKING:
/* Acquire only the AUTOINC mutex. */
- mutex_enter(&m_prebuilt->table->autoinc_mutex);
+ m_prebuilt->table->autoinc_mutex.lock();
break;
case AUTOINC_NEW_STYLE_LOCKING:
@@ -7876,24 +7874,19 @@ ha_innobase::innobase_lock_autoinc(void)
transaction has already acquired the AUTOINC lock on
behalf of a LOAD FILE or INSERT ... SELECT etc. type of
statement. */
- if (thd_sql_command(m_user_thd) == SQLCOM_INSERT
- || thd_sql_command(m_user_thd) == SQLCOM_REPLACE
- || thd_sql_command(m_user_thd) == SQLCOM_END // RBR event
- ) {
-
+ switch (thd_sql_command(m_user_thd)) {
+ case SQLCOM_INSERT:
+ case SQLCOM_REPLACE:
+ case SQLCOM_END: // RBR event
/* Acquire the AUTOINC mutex. */
- mutex_enter(&m_prebuilt->table->autoinc_mutex);
-
+ m_prebuilt->table->autoinc_mutex.lock();
/* We need to check that another transaction isn't
already holding the AUTOINC lock on the table. */
- if (m_prebuilt->table->n_waiting_or_granted_auto_inc_locks) {
- /* Release the mutex to avoid deadlocks and
- fall back to old style locking. */
- mutex_exit(&m_prebuilt->table->autoinc_mutex);
- } else {
+ if (!m_prebuilt->table->n_waiting_or_granted_auto_inc_locks) {
/* Do not fall back to old style locking. */
- break;
+ DBUG_RETURN(error);
}
+ m_prebuilt->table->autoinc_mutex.unlock();
}
/* Use old style locking. */
/* fall through */
@@ -7905,7 +7898,7 @@ ha_innobase::innobase_lock_autoinc(void)
if (error == DB_SUCCESS) {
/* Acquire the AUTOINC mutex. */
- mutex_enter(&m_prebuilt->table->autoinc_mutex);
+ m_prebuilt->table->autoinc_mutex.lock();
}
break;
@@ -7933,7 +7926,7 @@ ha_innobase::innobase_set_max_autoinc(
if (error == DB_SUCCESS) {
dict_table_autoinc_update_if_greater(m_prebuilt->table, auto_inc);
- mutex_exit(&m_prebuilt->table->autoinc_mutex);
+ m_prebuilt->table->autoinc_mutex.unlock();
}
return(error);
@@ -12782,7 +12775,7 @@ create_table_info_t::create_table_update_dict()
autoinc = 1;
}
- mutex_enter(&innobase_table->autoinc_mutex);
+ innobase_table->autoinc_mutex.lock();
dict_table_autoinc_initialize(innobase_table, autoinc);
if (innobase_table->is_temporary()) {
@@ -12807,7 +12800,7 @@ create_table_info_t::create_table_update_dict()
}
}
- mutex_exit(&innobase_table->autoinc_mutex);
+ innobase_table->autoinc_mutex.unlock();
}
innobase_parse_hint_from_comment(m_thd, innobase_table, m_form->s);
@@ -16497,7 +16490,7 @@ ha_innobase::innobase_get_autoinc(
/* It should have been initialized during open. */
if (*value == 0) {
m_prebuilt->autoinc_error = DB_UNSUPPORTED;
- mutex_exit(&m_prebuilt->table->autoinc_mutex);
+ m_prebuilt->table->autoinc_mutex.unlock();
}
}
@@ -16521,7 +16514,7 @@ ha_innobase::innobase_peek_autoinc(void)
innodb_table = m_prebuilt->table;
- mutex_enter(&innodb_table->autoinc_mutex);
+ innodb_table->autoinc_mutex.lock();
auto_inc = dict_table_autoinc_read(innodb_table);
@@ -16530,7 +16523,7 @@ ha_innobase::innobase_peek_autoinc(void)
" '" << innodb_table->name << "'";
}
- mutex_exit(&innodb_table->autoinc_mutex);
+ innodb_table->autoinc_mutex.unlock();
return(auto_inc);
}
@@ -16637,7 +16630,7 @@ ha_innobase::get_auto_increment(
/* Out of range number. Let handler::update_auto_increment()
take care of this */
m_prebuilt->autoinc_last_value = 0;
- mutex_exit(&m_prebuilt->table->autoinc_mutex);
+ m_prebuilt->table->autoinc_mutex.unlock();
*nb_reserved_values= 0;
return;
}
@@ -16680,7 +16673,7 @@ ha_innobase::get_auto_increment(
m_prebuilt->autoinc_offset = offset;
m_prebuilt->autoinc_increment = increment;
- mutex_exit(&m_prebuilt->table->autoinc_mutex);
+ m_prebuilt->table->autoinc_mutex.unlock();
}
/*******************************************************************//**
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 35309fc1b54..c5f1ef96ea6 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -291,7 +291,6 @@ UNIV_INLINE
void
dict_table_autoinc_initialize(dict_table_t* table, ib_uint64_t value)
{
- ut_ad(mutex_own(&table->autoinc_mutex));
table->autoinc = value;
}
@@ -304,7 +303,6 @@ UNIV_INLINE
ib_uint64_t
dict_table_autoinc_read(const dict_table_t* table)
{
- ut_ad(mutex_own(&table->autoinc_mutex));
return(table->autoinc);
}
@@ -318,8 +316,6 @@ UNIV_INLINE
bool
dict_table_autoinc_update_if_greater(dict_table_t* table, ib_uint64_t value)
{
- ut_ad(mutex_own(&table->autoinc_mutex));
-
if (value > table->autoinc) {
table->autoinc = value;
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 259da23fcd9..ed392df3c05 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -51,6 +51,7 @@ Created 1/8/1996 Heikki Tuuri
#include <algorithm>
#include <iterator>
#include <ostream>
+#include <mutex>
/* Forward declaration. */
struct ib_rbt_t;
@@ -932,7 +933,9 @@ extern ulong zip_pad_max;
an uncompressed page should be left as padding to avoid compression
failures. This estimate is based on a self-adapting heuristic. */
struct zip_pad_info_t {
- SysMutex mutex; /*!< mutex protecting the info */
+ /** Dummy assignment operator for dict_index_t::clone() */
+ zip_pad_info_t &operator=(const zip_pad_info_t&) { return *this; }
+ std::mutex mutex; /*!< mutex protecting the info */
Atomic_relaxed<ulint>
pad; /*!< number of bytes used as pad */
ulint success;/*!< successful compression ops during
@@ -2240,7 +2243,7 @@ public:
lock_t* autoinc_lock;
/** Mutex protecting the autoincrement counter. */
- ib_mutex_t autoinc_mutex;
+ std::mutex autoinc_mutex;
/** Autoinc counter value to give to the next inserted row. */
ib_uint64_t autoinc;
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index ddbfa451d22..28d954df8c1 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -50,7 +50,6 @@ instrumentation due to their large number of instances. */
#ifdef UNIV_PFS_MUTEX
/* Key defines to register InnoDB mutexes with performance schema */
-extern mysql_pfs_key_t autoinc_mutex_key;
extern mysql_pfs_key_t buffer_block_mutex_key;
extern mysql_pfs_key_t buf_pool_mutex_key;
extern mysql_pfs_key_t buf_pool_zip_mutex_key;
@@ -105,7 +104,6 @@ extern mysql_pfs_key_t event_mutex_key;
extern mysql_pfs_key_t event_manager_mutex_key;
extern mysql_pfs_key_t sync_array_mutex_key;
extern mysql_pfs_key_t thread_mutex_key;
-extern mysql_pfs_key_t zip_pad_mutex_key;
extern mysql_pfs_key_t row_drop_list_mutex_key;
extern mysql_pfs_key_t rw_trx_hash_element_mutex_key;
#endif /* UNIV_PFS_MUTEX */
diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h
index 4d2a7c8ff28..32fdc89d6e4 100644
--- a/storage/innobase/include/sync0types.h
+++ b/storage/innobase/include/sync0types.h
@@ -253,7 +253,6 @@ enum latch_level_t {
SYNC_IBUF_HEADER,
SYNC_DICT_HEADER,
SYNC_STATS_AUTO_RECALC,
- SYNC_DICT_AUTOINC_MUTEX,
SYNC_DICT,
SYNC_FTS_CACHE,
@@ -282,7 +281,6 @@ enum latch_level_t {
up its meta-data. See sync0debug.c. */
enum latch_id_t {
LATCH_ID_NONE = 0,
- LATCH_ID_AUTOINC,
LATCH_ID_BUF_BLOCK_MUTEX,
LATCH_ID_BUF_POOL,
LATCH_ID_BUF_POOL_ZIP,
@@ -335,7 +333,6 @@ enum latch_id_t {
LATCH_ID_EVENT_MANAGER,
LATCH_ID_EVENT_MUTEX,
LATCH_ID_SYNC_ARRAY_MUTEX,
- LATCH_ID_ZIP_PAD_MUTEX,
LATCH_ID_OS_AIO_READ_MUTEX,
LATCH_ID_OS_AIO_WRITE_MUTEX,
LATCH_ID_OS_AIO_LOG_MUTEX,
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 95832e3e147..eb94aad207c 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -1607,7 +1607,7 @@ page_zip_fields_free(
{
if (index) {
dict_table_t* table = index->table;
- mutex_free(&index->zip_pad.mutex);
+ index->zip_pad.mutex.~mutex();
mem_heap_free(index->heap);
dict_mem_table_free(table);
diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc
index d1ebcd52df3..485e867dfe6 100644
--- a/storage/innobase/sync/sync0debug.cc
+++ b/storage/innobase/sync/sync0debug.cc
@@ -505,7 +505,6 @@ LatchDebug::LatchDebug()
LEVEL_MAP_INSERT(SYNC_IBUF_HEADER);
LEVEL_MAP_INSERT(SYNC_DICT_HEADER);
LEVEL_MAP_INSERT(SYNC_STATS_AUTO_RECALC);
- LEVEL_MAP_INSERT(SYNC_DICT_AUTOINC_MUTEX);
LEVEL_MAP_INSERT(SYNC_DICT);
LEVEL_MAP_INSERT(SYNC_FTS_CACHE);
LEVEL_MAP_INSERT(SYNC_DICT_OPERATION);
@@ -765,7 +764,6 @@ LatchDebug::check_order(
case SYNC_NOREDO_RSEG:
case SYNC_PURGE_LATCH:
case SYNC_PURGE_QUEUE:
- case SYNC_DICT_AUTOINC_MUTEX:
case SYNC_DICT_OPERATION:
case SYNC_DICT_HEADER:
case SYNC_TRX_I_S_RWLOCK:
@@ -1276,8 +1274,6 @@ sync_latch_meta_init()
/* The latches should be ordered on latch_id_t. So that we can
index directly into the vector to update and fetch meta-data. */
- LATCH_ADD_MUTEX(AUTOINC, SYNC_DICT_AUTOINC_MUTEX, autoinc_mutex_key);
-
#if defined PFS_SKIP_BUFFER_MUTEX_RWLOCK || defined PFS_GROUP_BUFFER_SYNC
LATCH_ADD_MUTEX(BUF_BLOCK_MUTEX, SYNC_BUF_BLOCK, PFS_NOT_INSTRUMENTED);
#else
@@ -1417,8 +1413,6 @@ sync_latch_meta_init()
LATCH_ADD_MUTEX(SYNC_ARRAY_MUTEX, SYNC_NO_ORDER_CHECK,
sync_array_mutex_key);
- LATCH_ADD_MUTEX(ZIP_PAD_MUTEX, SYNC_NO_ORDER_CHECK, zip_pad_mutex_key);
-
LATCH_ADD_MUTEX(OS_AIO_READ_MUTEX, SYNC_NO_ORDER_CHECK,
PFS_NOT_INSTRUMENTED);
diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc
index c52064c7bb9..6b365b86ace 100644
--- a/storage/innobase/sync/sync0sync.cc
+++ b/storage/innobase/sync/sync0sync.cc
@@ -35,8 +35,6 @@ Created 9/5/1995 Heikki Tuuri
#include "sync0sync.h"
#ifdef UNIV_PFS_MUTEX
-/* Key to register autoinc_mutex with performance schema */
-mysql_pfs_key_t autoinc_mutex_key;
mysql_pfs_key_t buffer_block_mutex_key;
mysql_pfs_key_t buf_pool_mutex_key;
mysql_pfs_key_t buf_pool_zip_mutex_key;
@@ -91,7 +89,6 @@ mysql_pfs_key_t event_mutex_key;
mysql_pfs_key_t event_manager_mutex_key;
mysql_pfs_key_t sync_array_mutex_key;
mysql_pfs_key_t thread_mutex_key;
-mysql_pfs_key_t zip_pad_mutex_key;
mysql_pfs_key_t row_drop_list_mutex_key;
mysql_pfs_key_t rw_trx_hash_element_mutex_key;
#endif /* UNIV_PFS_MUTEX */