summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-05-17 15:17:37 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-17 15:26:33 +0300
commit198ed24cac6609e68687841c022efacdc9719d5f (patch)
treefb43f454e6b7e3b6b22c34051c7d9ce44e067b30
parentb390447e71cc3cbd4dc677efeabef771a0a77d64 (diff)
downloadmariadb-git-198ed24cac6609e68687841c022efacdc9719d5f.tar.gz
MDEV-19513: Rename dict_operation_lock to dict_sys.latch
dict_sys.lock(), dict_sys_lock(): Acquire both mutex and latch. dict_sys.unlock(), dict_sys_unlock(): Release both mutex and latch. dict_sys.assert_locked(): Assert that both mutex and latch are held.
-rw-r--r--storage/innobase/dict/dict0crea.cc3
-rw-r--r--storage/innobase/dict/dict0defrag_bg.cc18
-rw-r--r--storage/innobase/dict/dict0dict.cc54
-rw-r--r--storage/innobase/dict/dict0load.cc17
-rw-r--r--storage/innobase/dict/dict0stats.cc82
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc2
-rw-r--r--storage/innobase/fil/fil0fil.cc11
-rw-r--r--storage/innobase/handler/ha_innodb.cc6
-rw-r--r--storage/innobase/handler/handler0alter.cc40
-rw-r--r--storage/innobase/handler/i_s.cc30
-rw-r--r--storage/innobase/include/dict0dict.h36
-rw-r--r--storage/innobase/include/dict0mem.h7
-rw-r--r--storage/innobase/include/fil0fil.h2
-rw-r--r--storage/innobase/include/log0log.ic4
-rw-r--r--storage/innobase/include/row0mysql.h2
-rw-r--r--storage/innobase/include/trx0trx.h6
-rw-r--r--storage/innobase/row/row0import.cc10
-rw-r--r--storage/innobase/row/row0ins.cc6
-rw-r--r--storage/innobase/row/row0log.cc2
-rw-r--r--storage/innobase/row/row0merge.cc15
-rw-r--r--storage/innobase/row/row0mysql.cc32
-rw-r--r--storage/innobase/row/row0purge.cc16
-rw-r--r--storage/innobase/row/row0umod.cc4
-rw-r--r--storage/innobase/row/row0undo.cc2
-rw-r--r--storage/innobase/row/row0upd.cc6
-rw-r--r--storage/innobase/srv/srv0srv.cc8
26 files changed, 169 insertions, 252 deletions
diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc
index 59572fd11dd..71a4fd87c86 100644
--- a/storage/innobase/dict/dict0crea.cc
+++ b/storage/innobase/dict/dict0crea.cc
@@ -2327,8 +2327,7 @@ dict_delete_tablespace_and_datafiles(
{
dberr_t err = DB_SUCCESS;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
ut_ad(srv_sys_tablespaces_open);
trx->op_info = "delete tablespace and datafiles from dictionary";
diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc
index bec6ce0b49a..6782ac69bef 100644
--- a/storage/innobase/dict/dict0defrag_bg.cc
+++ b/storage/innobase/dict/dict0defrag_bg.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2019, 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
@@ -244,8 +244,7 @@ dict_stats_save_defrag_summary(
return DB_SUCCESS;
}
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
ret = dict_stats_save_index_stat(index, now, "n_pages_freed",
index->stat_defrag_n_pages_freed,
@@ -254,8 +253,7 @@ dict_stats_save_defrag_summary(
" last defragmentation run.",
NULL);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
return (ret);
}
@@ -295,9 +293,7 @@ dict_stats_save_defrag_stats(
return DB_SUCCESS;
}
- rw_lock_x_lock(dict_operation_lock);
-
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
ret = dict_stats_save_index_stat(index, now, "n_page_split",
index->stat_defrag_n_page_split,
NULL,
@@ -327,8 +323,6 @@ dict_stats_save_defrag_stats(
NULL);
end:
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
-
- return (ret);
+ dict_sys_unlock();
+ return ret;
}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index c8c694ea9e8..cd829f43891 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -87,16 +87,6 @@ ib_warn_row_too_big(const dict_table_t* table);
/** the dictionary system */
dict_sys_t dict_sys;
-/** @brief the data dictionary rw-latch protecting dict_sys
-
-table create, drop, etc. reserve this in X-mode; implicit or
-backround operations purge, rollback, foreign key checks reserve this
-in S-mode; we cannot trust that MySQL protects implicit or background
-operations a table drop since MySQL does not know of them; therefore
-we need this; NOTE: a transaction which reserves this must keep book
-on the mode in trx_t::dict_operation_lock_mode */
-rw_lock_t* dict_operation_lock;
-
/** Percentage of compression failures that are allowed in a single
round */
ulong zip_failure_threshold_pct = 5;
@@ -530,8 +520,7 @@ dict_table_close_and_drop(
{
dberr_t err = DB_SUCCESS;
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
ut_ad(trx->dict_operation != TRX_DICT_OP_NONE);
ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
@@ -1034,9 +1023,6 @@ dict_table_col_in_clustered_key(
void dict_sys_t::create()
{
ut_ad(!is_initialised());
- dict_operation_lock = static_cast<rw_lock_t*>(
- ut_zalloc_nokey(sizeof(*dict_operation_lock)));
-
ut_d(m_initialised= true);
UT_LIST_INIT(table_LRU, &dict_table_t::table_LRU);
UT_LIST_INIT(table_non_LRU, &dict_table_t::table_LRU);
@@ -1050,8 +1036,7 @@ void dict_sys_t::create()
table_id_hash= hash_create(hash_size);
temp_id_hash= hash_create(hash_size);
- rw_lock_create(dict_operation_lock_key,
- dict_operation_lock, SYNC_DICT_OPERATION);
+ rw_lock_create(dict_operation_lock_key, &latch, SYNC_DICT_OPERATION);
if (!srv_read_only_mode)
{
@@ -1260,9 +1245,7 @@ dict_table_can_be_evicted(
/*======================*/
dict_table_t* table) /*!< in: table to test */
{
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
-
+ ut_d(dict_sys.assert_locked());
ut_a(table->can_be_evicted);
ut_a(table->foreign_set.empty());
ut_a(table->referenced_set.empty());
@@ -1328,8 +1311,7 @@ dict_make_room_in_cache(
ut_a(pct_check > 0);
ut_a(pct_check <= 100);
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
ut_ad(dict_lru_validate());
i = len = UT_LIST_GET_LEN(dict_sys.table_LRU);
@@ -1939,9 +1921,7 @@ void dict_sys_t::remove(dict_table_t* table, bool lru, bool keep)
and free the index pages. */
trx_t* trx = trx_create();
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
-
+ ut_d(dict_sys.assert_locked());
/* Mimic row_mysql_lock_data_dictionary(). */
trx->dict_operation_lock_mode = RW_X_LATCH;
@@ -5817,8 +5797,7 @@ dict_index_set_merge_threshold(
ut_ad(!dict_table_is_comp(dict_sys.sys_tables));
ut_ad(!dict_table_is_comp(dict_sys.sys_indexes));
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
heap = mem_heap_create(sizeof(dtuple_t) + 2 * (sizeof(dfield_t)
+ sizeof(que_fork_t) + sizeof(upd_node_t)
@@ -5866,8 +5845,7 @@ dict_index_set_merge_threshold(
mtr_commit(&mtr);
mem_heap_free(heap);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
}
#ifdef UNIV_DEBUG
@@ -6449,11 +6427,7 @@ void dict_sys_t::close()
mutex_exit(&mutex);
mutex_free(&mutex);
-
- rw_lock_free(dict_operation_lock);
-
- ut_free(dict_operation_lock);
- dict_operation_lock = NULL;
+ rw_lock_free(&latch);
mutex_free(&dict_foreign_err_mutex);
@@ -6806,8 +6780,7 @@ dict_space_is_empty(
mtr_t mtr;
bool found = false;
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
mtr_start(&mtr);
for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
@@ -6828,8 +6801,7 @@ dict_space_is_empty(
}
mtr_commit(&mtr);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
return(!found);
}
@@ -6847,8 +6819,7 @@ dict_space_get_id(
ulint name_len = strlen(name);
ulint id = ULINT_UNDEFINED;
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
mtr_start(&mtr);
for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLESPACES);
@@ -6877,8 +6848,7 @@ dict_space_get_id(
}
mtr_commit(&mtr);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
return(id);
}
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 2c3e9c9e1f5..ef87a0e7422 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -884,8 +884,7 @@ dict_update_filepath(
dberr_t err = DB_SUCCESS;
trx_t* trx;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
trx = trx_create();
trx->op_info = "update filepath";
@@ -952,8 +951,7 @@ dict_replace_tablespace_and_filepath(
DBUG_EXECUTE_IF("innodb_fail_to_update_tablespace_dict",
return(DB_INTERRUPTED););
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
ut_ad(filepath);
trx = trx_create();
@@ -1350,8 +1348,7 @@ static ulint dict_check_sys_tables()
DBUG_ENTER("dict_check_sys_tables");
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
mtr_start(&mtr);
@@ -1487,8 +1484,7 @@ void dict_check_tablespaces_and_store_max_id()
DBUG_ENTER("dict_check_tablespaces_and_store_max_id");
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
/* Initialize the max space_id from sys header */
mtr_start(&mtr);
@@ -1505,8 +1501,7 @@ void dict_check_tablespaces_and_store_max_id()
max_space_id = dict_check_sys_tables();
fil_set_max_space_id_if_bigger(max_space_id);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
DBUG_VOID_RETURN;
}
@@ -2833,7 +2828,7 @@ dict_load_tablespace(
}
/* Try to open the tablespace. We set the 2nd param (fix_dict) to
- false because we do not have an x-lock on dict_operation_lock */
+ false because we do not have an x-lock on dict_sys.latch */
table->space = fil_ibd_open(
true, false, FIL_TYPE_TABLESPACE, table->space_id,
dict_tf_to_fsp_flags(table->flags),
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index d557078de49..0ebbcebb708 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2009, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2019, 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
@@ -283,8 +283,7 @@ dict_stats_exec_sql(
dberr_t err;
bool trx_started = false;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
if (!dict_stats_persistent_storage_check(true)) {
pars_info_free(pinfo);
@@ -2313,8 +2312,7 @@ dict_stats_save_index_stat(
char table_utf8[MAX_TABLE_UTF8_LEN];
ut_ad(!trx || trx->internal || trx->mysql_thd);
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
dict_fs2utf8(index->table->name.m_name, db_utf8, sizeof(db_utf8),
table_utf8, sizeof(table_utf8));
@@ -2449,8 +2447,7 @@ dict_stats_save(
table_utf8, sizeof(table_utf8));
now = ut_time();
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
pinfo = pars_info_create();
@@ -2488,13 +2485,10 @@ dict_stats_save(
if (ret != DB_SUCCESS) {
ib::error() << "Cannot save table statistics for table "
<< table->name << ": " << ut_strerr(ret);
-
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
-
+func_exit:
+ dict_sys_unlock();
dict_stats_snapshot_free(table);
-
- return(ret);
+ return ret;
}
trx_t* trx = trx_create();
@@ -2595,13 +2589,7 @@ dict_stats_save(
end:
trx_free(trx);
-
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
-
- dict_stats_snapshot_free(table);
-
- return(ret);
+ goto func_exit;
}
/*********************************************************************//**
@@ -3406,8 +3394,7 @@ dict_stats_drop_index(
pars_info_add_str_literal(pinfo, "index_name", iname);
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
ret = dict_stats_exec_sql(
pinfo,
@@ -3419,8 +3406,7 @@ dict_stats_drop_index(
"index_name = :index_name;\n"
"END;\n", NULL);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
if (ret == DB_STATS_DO_NOT_EXIST) {
ret = DB_SUCCESS;
@@ -3468,8 +3454,7 @@ dict_stats_delete_from_table_stats(
pars_info_t* pinfo;
dberr_t ret;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
pinfo = pars_info_create();
@@ -3504,8 +3489,7 @@ dict_stats_delete_from_index_stats(
pars_info_t* pinfo;
dberr_t ret;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
pinfo = pars_info_create();
@@ -3541,8 +3525,7 @@ dict_stats_drop_table(
char table_utf8[MAX_TABLE_UTF8_LEN];
dberr_t ret;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
/* skip tables that do not contain a database name
e.g. if we are dropping SYS_TABLES */
@@ -3617,8 +3600,7 @@ dict_stats_rename_table_in_table_stats(
pars_info_t* pinfo;
dberr_t ret;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
pinfo = pars_info_create();
@@ -3661,8 +3643,7 @@ dict_stats_rename_table_in_index_stats(
pars_info_t* pinfo;
dberr_t ret;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
pinfo = pars_info_create();
@@ -3705,9 +3686,6 @@ dict_stats_rename_table(
char new_table_utf8[MAX_TABLE_UTF8_LEN];
dberr_t ret;
- ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(!mutex_own(&dict_sys.mutex));
-
/* skip innodb_table_stats and innodb_index_stats themselves */
if (strcmp(old_name, TABLE_STATS_NAME) == 0
|| strcmp(old_name, INDEX_STATS_NAME) == 0
@@ -3723,8 +3701,7 @@ dict_stats_rename_table(
dict_fs2utf8(new_name, new_db_utf8, sizeof(new_db_utf8),
new_table_utf8, sizeof(new_table_utf8));
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
ulint n_attempts = 0;
do {
@@ -3744,11 +3721,9 @@ dict_stats_rename_table(
}
if (ret != DB_SUCCESS) {
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
os_thread_sleep(200000 /* 0.2 sec */);
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
}
} while ((ret == DB_DEADLOCK
|| ret == DB_DUPLICATE_KEY
@@ -3776,8 +3751,7 @@ dict_stats_rename_table(
TABLE_STATS_NAME_PRINT,
new_db_utf8, new_table_utf8,
old_db_utf8, old_table_utf8);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
return(ret);
}
/* else */
@@ -3800,19 +3774,16 @@ dict_stats_rename_table(
}
if (ret != DB_SUCCESS) {
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
os_thread_sleep(200000 /* 0.2 sec */);
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
}
} while ((ret == DB_DEADLOCK
|| ret == DB_DUPLICATE_KEY
|| ret == DB_LOCK_WAIT_TIMEOUT)
&& n_attempts < 5);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
if (ret != DB_SUCCESS) {
snprintf(errstr, errstr_sz,
@@ -3853,12 +3824,10 @@ dict_stats_rename_index(
const char* old_index_name, /*!< in: old index name */
const char* new_index_name) /*!< in: new index name */
{
- rw_lock_x_lock(dict_operation_lock);
- mutex_enter(&dict_sys.mutex);
+ dict_sys_lock();
if (!dict_stats_persistent_storage_check(true)) {
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
return(DB_STATS_DO_NOT_EXIST);
}
@@ -3891,8 +3860,7 @@ dict_stats_rename_index(
"index_name = :old_index_name;\n"
"END;\n", NULL);
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
return(ret);
}
diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc
index 9bd4b6c8ce4..1d58ca196d9 100644
--- a/storage/innobase/dict/dict0stats_bg.cc
+++ b/storage/innobase/dict/dict0stats_bg.cc
@@ -313,7 +313,7 @@ dict_stats_thread_init()
dict_stats_update_if_needed() is called and it may be acquired
inside that function (thus a level <=SYNC_DICT would do).
3) from row_drop_table_for_mysql() after dict_sys.mutex (SYNC_DICT)
- and dict_operation_lock (SYNC_DICT_OPERATION) have been locked
+ and dict_sys.latch (SYNC_DICT_OPERATION) have been locked
(thus a level <SYNC_DICT && <SYNC_DICT_OPERATION would do)
So we choose SYNC_STATS_AUTO_RECALC to be about below SYNC_DICT. */
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index e4fb839a7cc..1dbf64e3fb9 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -3178,11 +3178,12 @@ fil_ibd_open(
ulint tablespaces_found = 0;
ulint valid_tablespaces_found = 0;
- ut_ad(!fix_dict || rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ if (fix_dict) {
+ ut_d(dict_sys.assert_locked());
+ ut_ad(!srv_read_only_mode);
+ ut_ad(srv_log_file_size != 0);
+ }
- ut_ad(!fix_dict || mutex_own(&dict_sys.mutex));
- ut_ad(!fix_dict || !srv_read_only_mode);
- ut_ad(!fix_dict || srv_log_file_size != 0);
ut_ad(fil_type_is_data(purpose));
/* Table flags can be ULINT_UNDEFINED if
@@ -4766,7 +4767,7 @@ fil_space_validate_for_mtr_commit(
/* We are serving mtr_commit(). While there is an active
mini-transaction, we should have !space->stop_new_ops. This is
guaranteed by meta-data locks or transactional locks, or
- dict_operation_lock (X-lock in DROP, S-lock in purge).
+ dict_sys.latch (X-lock in DROP, S-lock in purge).
However, a file I/O thread can invoke change buffer merge
while fil_check_pending_operations() is waiting for operations
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 167c6589e22..83bddd439dd 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -20452,10 +20452,10 @@ for purge thread */
static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table)
{
if (THDVAR(thd, background_thread)) {
- /* Purge thread acquires dict_operation_lock while
- processing undo log record. Release the dict_operation_lock
+ /* Purge thread acquires dict_sys.latch while
+ processing undo log record. Release it
before acquiring MDL on the table. */
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
return innodb_acquire_mdl(thd, table);
} else {
if (table->vc_templ->mysql_table_query_id
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 85561c08d77..a8cf53b5033 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -746,8 +746,7 @@ inline void dict_table_t::rollback_instant(
const char* old_v_col_names,
const ulint* col_map)
{
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
dict_index_t* index = indexes.start;
mtr_t mtr;
mtr.start();
@@ -4741,8 +4740,7 @@ innobase_update_gis_column_type(
DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
info = pars_info_create();
@@ -6733,7 +6731,7 @@ new_clustered_failed:
ut_a(ctx->new_table == temp_table);
/* n_ref_count must be 1, because purge cannot
be executing on this very table as we are
- holding dict_operation_lock X-latch. */
+ holding dict_sys.latch X-latch. */
DBUG_ASSERT(ctx->new_table->get_ref_count() == 1);
DBUG_ASSERT(ctx->new_table->id != 0);
DBUG_ASSERT(ctx->new_table->id == ctx->trx->table_id);
@@ -6946,8 +6944,7 @@ error_handling_drop_uncached:
op_ok:
#endif /* UNIV_DEBUG */
ut_ad(ctx->trx->dict_operation_lock_mode == RW_X_LATCH);
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
DICT_TF2_FLAG_SET(ctx->new_table, DICT_TF2_FTS);
if (ctx->need_rebuild()) {
@@ -7091,7 +7088,7 @@ error_handled:
trx_commit_for_mysql(ctx->trx);
/* n_ref_count must be 1, because purge cannot
be executing on this very table as we are
- holding dict_operation_lock X-latch. */
+ holding dict_sys.latch X-latch. */
DBUG_ASSERT(user_table->get_ref_count() == 1 || ctx->online);
online_retry_drop_indexes_with_trx(user_table, ctx->trx);
@@ -7233,9 +7230,7 @@ rename_index_try(
trx_t* trx)
{
DBUG_ENTER("rename_index_try");
-
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
pars_info_t* pinfo;
@@ -7293,9 +7288,7 @@ void
innobase_rename_index_cache(dict_index_t* index, const char* new_name)
{
DBUG_ENTER("innobase_rename_index_cache");
-
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
size_t old_name_len = strlen(index->name);
size_t new_name_len = strlen(new_name);
@@ -8261,10 +8254,7 @@ ha_innobase::inplace_alter_table(
bool rebuild_templ = false;
DBUG_ENTER("inplace_alter_table");
DBUG_ASSERT(!srv_read_only_mode);
-
ut_ad(!sync_check_iterate(sync_check()));
- ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_S));
DEBUG_SYNC(m_user_thd, "innodb_inplace_alter_table_enter");
@@ -8476,10 +8466,7 @@ innobase_online_rebuild_log_free(
dict_table_t* table)
{
dict_index_t* clust_index = dict_table_get_first_index(table);
-
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
-
+ ut_d(dict_sys.assert_locked());
rw_lock_x_lock(&clust_index->lock);
if (clust_index->online_log) {
@@ -8752,8 +8739,7 @@ innobase_drop_foreign_try(
DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
/* Drop the constraint from the data dictionary. */
static const char sql[] =
@@ -8811,8 +8797,7 @@ innobase_rename_column_try(
DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
if (new_clustered) {
goto rename_foreign;
@@ -9088,8 +9073,7 @@ innobase_rename_or_enlarge_column_try(
DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
ulint n_base;
@@ -10512,7 +10496,7 @@ alter_stats_norebuild(
in a separate transaction from trx, because lock waits are not
allowed in a data dictionary transaction. (Lock waits are possible
on the statistics table, because it is directly accessible by users,
- not covered by the dict_operation_lock.)
+ not covered by the dict_sys.latch.)
Because the data dictionary changes were already committed, orphaned
rows may be left in the statistics table if the system crashes.
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 6369b024a58..110bf8bb119 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -2869,19 +2869,19 @@ i_s_fts_deleted_generic_fill(
}
/* Prevent DDL to drop fts aux tables. */
- rw_lock_s_lock(dict_operation_lock);
+ rw_lock_s_lock(&dict_sys.latch);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
if (!user_table) {
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_RETURN(0);
} else if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_RETURN(0);
}
@@ -2917,7 +2917,7 @@ i_s_fts_deleted_generic_fill(
dict_table_close(user_table, FALSE, FALSE);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_RETURN(ret);
}
@@ -3730,13 +3730,13 @@ i_s_fts_index_table_fill(
}
/* Prevent DDL to drop fts aux tables. */
- rw_lock_s_lock(dict_operation_lock);
+ rw_lock_s_lock(&dict_sys.latch);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
if (!user_table) {
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_RETURN(0);
}
@@ -3757,7 +3757,7 @@ i_s_fts_index_table_fill(
dict_table_close(user_table, FALSE, FALSE);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
ut_free(conv_str.f_str);
@@ -3899,19 +3899,19 @@ i_s_fts_config_fill(
fields = table->field;
/* Prevent DDL to drop fts aux tables. */
- rw_lock_s_lock(dict_operation_lock);
+ rw_lock_s_lock(&dict_sys.latch);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
if (!user_table) {
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_RETURN(0);
} else if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_RETURN(0);
}
@@ -3971,7 +3971,7 @@ i_s_fts_config_fill(
dict_table_close(user_table, FALSE, FALSE);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_RETURN(ret);
}
@@ -6338,7 +6338,7 @@ i_s_sys_tables_fill_table_stats(
}
heap = mem_heap_create(1000);
- rw_lock_s_lock(dict_operation_lock);
+ rw_lock_s_lock(&dict_sys.latch);
mutex_enter(&dict_sys.mutex);
mtr_start(&mtr);
@@ -6372,11 +6372,11 @@ i_s_sys_tables_fill_table_stats(
err_msg);
}
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
mem_heap_empty(heap);
/* Get the next record */
- rw_lock_s_lock(dict_operation_lock);
+ rw_lock_s_lock(&dict_sys.latch);
mutex_enter(&dict_sys.mutex);
mtr_start(&mtr);
@@ -6385,7 +6385,7 @@ i_s_sys_tables_fill_table_stats(
mtr_commit(&mtr);
mutex_exit(&dict_sys.mutex);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
mem_heap_free(heap);
DBUG_RETURN(0);
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 9146627b496..ae223acd07f 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1471,6 +1471,15 @@ public:
and DROP TABLE, as well as reading
the dictionary data for a table from
system tables */
+ /** @brief the data dictionary rw-latch protecting dict_sys
+
+ Table create, drop, etc. reserve this in X-mode; implicit or
+ backround operations purge, rollback, foreign key checks reserve this
+ in S-mode; not all internal InnoDB operations are covered by MDL.
+
+ This latch also prevents lock waits when accessing the InnoDB
+ data dictionary tables. @see trx_t::dict_operation_lock_mode */
+ rw_lock_t latch;
row_id_t row_id; /*!< the next row id to assign;
NOTE that at a checkpoint this
must be written to the dict system
@@ -1501,7 +1510,6 @@ private:
/** hash table of temporary table IDs */
hash_table_t* temp_id_hash;
public:
-
/** @return a new temporary table ID */
table_id_t get_temporary_table_id() {
return temp_table_id.fetch_add(1, std::memory_order_relaxed);
@@ -1603,14 +1611,36 @@ 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));
+ ut_ad(rw_lock_own(&latch, RW_LOCK_X));
+ }
+#endif
+ /** Lock the data dictionary cache. */
+ void lock(const char* file, unsigned line)
+ {
+ rw_lock_x_lock_func(&latch, 0, file, line);
+ mutex_enter_loc(&mutex, file, line);
+ }
+
+ /** Unlock the data dictionary cache. */
+ void unlock()
+ {
+ mutex_exit(&mutex);
+ rw_lock_x_unlock(&latch);
+ }
};
/** the data dictionary cache */
extern dict_sys_t dict_sys;
-/** the data dictionary rw-latch protecting dict_sys */
-extern rw_lock_t* dict_operation_lock;
#define dict_table_prevent_eviction(table) dict_sys.prevent_eviction(table)
+#define dict_sys_lock() dict_sys.lock(__FILE__, __LINE__)
+#define dict_sys_unlock() dict_sys.unlock()
/** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */
extern dict_index_t* dict_ind_redundant;
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index cee16102b2e..b646537b4c3 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -948,12 +948,12 @@ struct dict_index_t {
dictionary cache */
unsigned to_be_dropped:1;
/*!< TRUE if the index is to be dropped;
- protected by dict_operation_lock */
+ protected by dict_sys.latch */
unsigned online_status:2;
/*!< enum online_index_status.
Transitions from ONLINE_INDEX_COMPLETE (to
ONLINE_INDEX_CREATION) are protected
- by dict_operation_lock and
+ by dict_sys.latch and
dict_sys.mutex. Other changes are
protected by index->lock. */
unsigned uncommitted:1;
@@ -1835,8 +1835,7 @@ public:
/** TRUE if the table is to be dropped, but not yet actually dropped
(could in the background drop list). It is turned on at the beginning
of row_drop_table_for_mysql() and turned off just before we start to
- update system tables for the drop. It is protected by
- dict_operation_lock. */
+ update system tables for the drop. It is protected by dict_sys.latch. */
unsigned to_be_dropped:1;
/** Number of non-virtual columns defined so far. */
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index bfbe3a3578f..68b8a45d993 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -134,7 +134,7 @@ struct fil_space_t {
the tablespace to disk; dropping of the
tablespace is forbidden if this is positive */
/** Number of pending buffer pool operations accessing the tablespace
- without holding a table lock or dict_operation_lock S-latch
+ without holding a table lock or dict_sys.latch S-latch
that would prevent the table (and tablespace) from being
dropped. An example is change buffer merge.
The tablespace cannot be dropped while this is nonzero,
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index a3de6356ad8..39214b621e1 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2019, 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
@@ -485,7 +485,7 @@ log_free_check(void)
static const latch_level_t latches[] = {
SYNC_DICT, /* dict_sys.mutex during
commit_try_rebuild() */
- SYNC_DICT_OPERATION, /* dict_operation_lock X-latch during
+ SYNC_DICT_OPERATION, /* dict_sys.latch X-latch during
commit_try_rebuild() */
SYNC_FTS_CACHE, /* fts_cache_t::lock */
SYNC_INDEX_TREE /* index->lock */
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 94307146e9e..167df0d3ec7 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -418,7 +418,7 @@ will remain locked.
@param[in] create_failed true=create table failed
because e.g. foreign key column
@param[in] nonatomic Whether it is permitted to release
- and reacquire dict_operation_lock
+ and reacquire dict_sys.latch
@return error code */
dberr_t
row_drop_table_for_mysql(
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index ee5f1c4aefb..a6eba0b1a92 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -690,7 +690,7 @@ with exactly one user transaction. There are some exceptions to this:
* For DDL operations, a subtransaction is allocated that modifies the
data dictionary tables. Lock waits and deadlocks are prevented by
-acquiring the dict_operation_lock before starting the subtransaction
+acquiring the dict_sys.latch before starting the subtransaction
and releasing it after committing the subtransaction.
* The purge system uses a special transaction that is not associated
@@ -924,8 +924,8 @@ public:
ib_uint32_t dict_operation_lock_mode;
/*!< 0, RW_S_LATCH, or RW_X_LATCH:
the latch mode trx currently holds
- on dict_operation_lock. Protected
- by dict_operation_lock. */
+ on dict_sys.latch. Protected
+ by dict_sys.latch. */
time_t start_time; /*!< time the state last time became
TRX_STATE_ACTIVE */
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 5455c969c7a..cf8008d55c4 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3856,7 +3856,7 @@ row_import_for_mysql(
/* Prevent DDL operations while we are checking. */
- rw_lock_s_lock_func(dict_operation_lock, 0, __FILE__, __LINE__);
+ rw_lock_s_lock(&dict_sys.latch);
row_import cfg;
@@ -3881,14 +3881,14 @@ row_import_for_mysql(
autoinc = cfg.m_autoinc;
}
- rw_lock_s_unlock_gen(dict_operation_lock, 0);
+ rw_lock_s_unlock(&dict_sys.latch);
DBUG_EXECUTE_IF("ib_import_set_index_root_failure",
err = DB_TOO_MANY_CONCURRENT_TRXS;);
} else if (cfg.m_missing) {
- rw_lock_s_unlock_gen(dict_operation_lock, 0);
+ rw_lock_s_unlock(&dict_sys.latch);
/* We don't have a schema file, we will have to discover
the index root pages from the .ibd file and skip the schema
@@ -3920,7 +3920,7 @@ row_import_for_mysql(
space_flags = fetchIndexRootPages.get_space_flags();
} else {
- rw_lock_s_unlock_gen(dict_operation_lock, 0);
+ rw_lock_s_unlock(&dict_sys.latch);
}
if (err != DB_SUCCESS) {
@@ -4011,7 +4011,7 @@ row_import_for_mysql(
/* Open the tablespace so that we can access via the buffer pool.
We set the 2nd param (fix_dict = true) here because we already
- have an x-lock on dict_operation_lock and dict_sys.mutex.
+ have an x-lock on dict_sys.latch and dict_sys.mutex.
The tablespace is initially opened as a temporary one, because
we will not be writing any redo log for it before we have invoked
fil_space_t::set_imported() to declare it a persistent tablespace. */
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index c4b6883156c..0cd49bce994 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1543,7 +1543,7 @@ row_ins_set_exclusive_rec_lock(
/***************************************************************//**
Checks if foreign key constraint fails for an index entry. Sets shared locks
which lock either the success or the failure of the constraint. NOTE that
-the caller must have a shared latch on dict_operation_lock.
+the caller must have a shared latch on dict_sys.latch.
@return DB_SUCCESS, DB_NO_REFERENCED_ROW, or DB_ROW_IS_REFERENCED */
dberr_t
row_ins_check_foreign_constraint(
@@ -1584,7 +1584,7 @@ row_ins_check_foreign_constraint(
upd_node= NULL;
#endif /* WITH_WSREP */
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S));
+ ut_ad(rw_lock_own(&dict_sys.latch, RW_LOCK_S));
err = DB_SUCCESS;
@@ -1990,7 +1990,7 @@ row_ins_check_foreign_constraints(
}
/* NOTE that if the thread ends up waiting for a lock
- we will release dict_operation_lock temporarily!
+ we will release dict_sys.latch temporarily!
But the counter on the table protects the referenced
table from being dropped while the check is running. */
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 834a31684b2..c0e98a5368b 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -3111,7 +3111,7 @@ row_log_table_apply(
stage->begin_phase_log_table();
- ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_S));
+ ut_ad(!rw_lock_own(&dict_sys.latch, RW_LOCK_S));
clust_index = dict_table_get_first_index(old_table);
if (clust_index->online_log->n_rows == 0) {
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 83c8316b523..aebdd09e5d6 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -3755,10 +3755,9 @@ row_merge_drop_index_dict(
pars_info_t* info;
ut_ad(!srv_read_only_mode);
- ut_ad(mutex_own(&dict_sys.mutex));
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
info = pars_info_create();
pars_info_add_ull_literal(info, "indexid", index_id);
@@ -3818,17 +3817,16 @@ row_merge_drop_indexes_dict(
pars_info_t* info;
ut_ad(!srv_read_only_mode);
- ut_ad(mutex_own(&dict_sys.mutex));
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
/* It is possible that table->n_ref_count > 1 when
locked=TRUE. In this case, all code that should have an open
handle to the table be waiting for the next statement to execute,
or waiting for a meta-data lock.
- A concurrent purge will be prevented by dict_operation_lock. */
+ A concurrent purge will be prevented by dict_sys.latch. */
info = pars_info_create();
pars_info_add_ull_literal(info, "tableid", table_id);
@@ -3868,10 +3866,9 @@ row_merge_drop_indexes(
dict_index_t* next_index;
ut_ad(!srv_read_only_mode);
- ut_ad(mutex_own(&dict_sys.mutex));
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
index = dict_table_get_first_index(table);
ut_ad(dict_index_is_clust(index));
@@ -3885,7 +3882,7 @@ row_merge_drop_indexes(
handle to the table be waiting for the next statement to execute,
or waiting for a meta-data lock.
- A concurrent purge will be prevented by dict_operation_lock. */
+ A concurrent purge will be prevented by dict_sys.latch. */
if (!locked && (table->get_ref_count() > 1
|| UT_LIST_GET_FIRST(table->locks))) {
@@ -4320,7 +4317,7 @@ row_merge_rename_tables_dict(
ut_ad(!srv_read_only_mode);
ut_ad(old_table != new_table);
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_TABLE
|| trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 1ddae8d4fc3..02b936b167c 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2121,7 +2121,7 @@ row_mysql_freeze_data_dictionary_func(
{
ut_a(trx->dict_operation_lock_mode == 0);
- rw_lock_s_lock_inline(dict_operation_lock, 0, file, line);
+ rw_lock_s_lock_inline(&dict_sys.latch, 0, file, line);
trx->dict_operation_lock_mode = RW_S_LATCH;
}
@@ -2137,7 +2137,7 @@ row_mysql_unfreeze_data_dictionary(
ut_a(trx->dict_operation_lock_mode == RW_S_LATCH);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
trx->dict_operation_lock_mode = 0;
}
@@ -2321,14 +2321,8 @@ row_mysql_lock_data_dictionary_func(
{
ut_a(trx->dict_operation_lock_mode == 0
|| trx->dict_operation_lock_mode == RW_X_LATCH);
-
- /* Serialize data dictionary operations with dictionary mutex:
- no deadlocks or lock waits can occur then in these operations */
-
- rw_lock_x_lock_inline(dict_operation_lock, 0, file, line);
+ dict_sys.lock(file, line);
trx->dict_operation_lock_mode = RW_X_LATCH;
-
- mutex_enter(&dict_sys.mutex);
}
/*********************************************************************//**
@@ -2339,16 +2333,9 @@ row_mysql_unlock_data_dictionary(
trx_t* trx) /*!< in/out: transaction */
{
ut_ad(lock_trx_has_sys_table_locks(trx) == NULL);
-
ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
-
- /* Serialize data dictionary operations with dictionary mutex:
- no deadlocks can occur then in these operations */
-
- mutex_exit(&dict_sys.mutex);
- rw_lock_x_unlock(dict_operation_lock);
-
trx->dict_operation_lock_mode = 0;
+ dict_sys.unlock();
}
/*********************************************************************//**
@@ -2370,8 +2357,7 @@ row_create_table_for_mysql(
que_thr_t* thr;
dberr_t err;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
DBUG_EXECUTE_IF(
@@ -2511,8 +2497,7 @@ row_create_index_for_mysql(
ulint len;
dict_table_t* table = index->table;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys.mutex));
+ ut_d(dict_sys.assert_locked());
for (i = 0; i < index->n_def; i++) {
/* Check that prefix_len and actual length
@@ -3303,7 +3288,7 @@ will remain locked.
@param[in] create_failed true=create table failed
because e.g. foreign key column
@param[in] nonatomic Whether it is permitted to release
- and reacquire dict_operation_lock
+ and reacquire dict_sys.latch
@return error code or DB_SUCCESS */
dberr_t
row_drop_table_for_mysql(
@@ -3342,8 +3327,7 @@ row_drop_table_for_mysql(
nonatomic = true;
}
- ut_ad(mutex_own(&dict_sys.mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_d(dict_sys.assert_locked());
table = dict_table_open_on_name(
name, TRUE, FALSE,
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index bafcb35fad8..c6a415a8d29 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -102,7 +102,7 @@ row_purge_remove_clust_if_poss_low(
purge_node_t* node, /*!< in/out: row purge node */
ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S)
+ ut_ad(rw_lock_own(&dict_sys.latch, RW_LOCK_S)
|| node->vcol_info.is_used());
dict_index_t* index = dict_table_get_first_index(node->table);
@@ -790,7 +790,7 @@ whose old history can no longer be observed.
@param[in,out] mtr mini-transaction (will be started and committed) */
static void row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr)
{
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S)
+ ut_ad(rw_lock_own(&dict_sys.latch, RW_LOCK_S)
|| node->vcol_info.is_used());
/* Reset DB_TRX_ID, DB_ROLL_PTR for old records. */
mtr->start();
@@ -867,7 +867,7 @@ row_purge_upd_exist_or_extern_func(
{
mem_heap_t* heap;
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_S)
+ ut_ad(rw_lock_own(&dict_sys.latch, RW_LOCK_S)
|| node->vcol_info.is_used());
ut_ad(!node->table->skip_alter_undo);
@@ -1058,7 +1058,7 @@ row_purge_parse_undo_rec(
for this row */
try_again:
- rw_lock_s_lock_inline(dict_operation_lock, 0, __FILE__, __LINE__);
+ rw_lock_s_lock_inline(&dict_sys.latch, 0, __FILE__, __LINE__);
node->table = dict_table_open_on_id(
table_id, FALSE, DICT_TABLE_OP_NORMAL);
@@ -1089,7 +1089,7 @@ try_again:
if (!mysqld_server_started) {
dict_table_close(node->table, FALSE, FALSE);
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
return(false);
}
@@ -1119,7 +1119,7 @@ inaccessible:
dict_table_close(node->table, FALSE, FALSE);
node->table = NULL;
err_exit:
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
node->skip(table_id, trx_id);
return(false);
}
@@ -1255,10 +1255,10 @@ row_purge(
node, undo_rec, thr, updated_extern);
if (!node->vcol_info.is_used()) {
- rw_lock_s_unlock(dict_operation_lock);
+ rw_lock_s_unlock(&dict_sys.latch);
}
- ut_ad(!rw_lock_own(dict_operation_lock, RW_LOCK_S));
+ ut_ad(!rw_lock_own(&dict_sys.latch, RW_LOCK_S));
if (purged
|| srv_shutdown_state != SRV_SHUTDOWN_NONE
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 9c8d3d3d313..64d0e812838 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -270,7 +270,7 @@ row_undo_mod_clust(
ut_ad(thr_get_trx(thr) == node->trx);
ut_ad(node->trx->dict_operation_lock_mode);
ut_ad(node->trx->in_rollback);
- ut_ad(rw_lock_own_flagged(dict_operation_lock,
+ ut_ad(rw_lock_own_flagged(&dict_sys.latch,
RW_LOCK_FLAG_X | RW_LOCK_FLAG_S));
log_free_check();
@@ -327,7 +327,7 @@ row_undo_mod_clust(
}
/* Online rebuild cannot be initiated while we are holding
- dict_operation_lock and index->lock. (It can be aborted.) */
+ dict_sys.latch and index->lock. (It can be aborted.) */
ut_ad(online || !dict_index_is_online_ddl(index));
if (err == DB_SUCCESS && online) {
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index b560ec2a0da..42df2318566 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -420,7 +420,7 @@ row_undo(
/* Prevent DROP TABLE etc. while we are rolling back this row.
If we are doing a TABLE CREATE or some other dictionary operation,
- then we already have dict_operation_lock locked in x-mode. Do not
+ then we already have dict_sys.latch locked in x-mode. Do not
try to lock again, because that would cause a hang. */
trx_t* trx = node->trx;
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index e1403eea93b..fe82cdf7e08 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -122,7 +122,7 @@ row_upd_changes_first_fields_binary(
Checks if index currently is mentioned as a referenced index in a foreign
key constraint.
-NOTE that since we do not hold dict_operation_lock when leaving the
+NOTE that since we do not hold dict_sys.latch when leaving the
function, it may be that the referencing table has been dropped when
we leave this function: this function is only for heuristic use!
@@ -289,7 +289,7 @@ row_upd_check_references_constraints(
}
/* NOTE that if the thread ends up waiting for a lock
- we will release dict_operation_lock temporarily!
+ we will release dict_sys.latch temporarily!
But the inc_fk_checks() protects foreign_table from
being dropped while the check is running. */
@@ -397,7 +397,7 @@ wsrep_row_upd_check_foreign_constraints(
}
/* NOTE that if the thread ends up waiting for a lock
- we will release dict_operation_lock temporarily!
+ we will release dict_sys.latch temporarily!
But the counter on the table protects 'foreign' from
being dropped while the check is running. */
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 8501ffbf672..260271bdc8d 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -1996,16 +1996,12 @@ srv_master_evict_from_table_cache(
{
ulint n_tables_evicted = 0;
- rw_lock_x_lock(dict_operation_lock);
-
- dict_mutex_enter_for_mysql();
+ dict_sys_lock();
n_tables_evicted = dict_make_room_in_cache(
innobase_get_table_cache_size(), pct_check);
- dict_mutex_exit_for_mysql();
-
- rw_lock_x_unlock(dict_operation_lock);
+ dict_sys_unlock();
return(n_tables_evicted);
}