diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-22 16:17:53 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-23 08:28:17 +0300 |
commit | 5f2628d1eea21d9732f582b77782b072e5e04014 (patch) | |
tree | ce8ad509e242d4acc5bd4e050acaf027a3d1c73f | |
parent | ddb8309e8c1bac8d419fe5c224665c6dca1e2878 (diff) | |
download | mariadb-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.cc | 14 | ||||
-rw-r--r-- | storage/innobase/dict/dict0mem.cc | 4 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 49 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.h | 4 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 7 | ||||
-rw-r--r-- | storage/innobase/include/sync0sync.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/sync0types.h | 3 | ||||
-rw-r--r-- | storage/innobase/page/page0zip.cc | 2 | ||||
-rw-r--r-- | storage/innobase/sync/sync0debug.cc | 6 | ||||
-rw-r--r-- | storage/innobase/sync/sync0sync.cc | 3 |
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 */ |