Skip to content

Commit

Permalink
MDEV-22778 Slow InnoDB shutdown on large instance
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dr-m committed Jul 23, 2020
1 parent ddb8309 commit 5f2628d
Show file tree
Hide file tree
Showing 10 changed files with 36 additions and 58 deletions.
14 changes: 7 additions & 7 deletions storage/innobase/dict/dict0dict.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
{
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

/*********************************************************************//**
Expand All @@ -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();
}

/*********************************************************************//**
Expand Down
4 changes: 2 additions & 2 deletions storage/innobase/dict/dict0mem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
49 changes: 21 additions & 28 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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 */
Expand All @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()) {
Expand All @@ -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);
Expand Down Expand Up @@ -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();
}
}

Expand All @@ -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);

Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
}

/*******************************************************************//**
Expand Down
4 changes: 0 additions & 4 deletions storage/innobase/include/dict0dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
}

Expand All @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions storage/innobase/include/dict0mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Created 1/8/1996 Heikki Tuuri
#include <algorithm>
#include <iterator>
#include <ostream>
#include <mutex>

/* Forward declaration. */
struct ib_rbt_t;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -2240,7 +2243,7 @@ struct dict_table_t {
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;
Expand Down
2 changes: 0 additions & 2 deletions storage/innobase/include/sync0sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
3 changes: 0 additions & 3 deletions storage/innobase/include/sync0types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/page/page0zip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 0 additions & 6 deletions storage/innobase/sync/sync0debug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);

Expand Down
3 changes: 0 additions & 3 deletions storage/innobase/sync/sync0sync.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 5f2628d

Please sign in to comment.