summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@mariadb.org>2019-06-13 16:04:47 +0400
committerSergey Vojtovich <svoj@mariadb.org>2019-06-13 16:04:47 +0400
commitb10f66ea18100e55a3afe53659f8fcc9a7eb05c8 (patch)
tree37cdc5f341a92a85105ed5d7d0e52ddeeda054d1
parentef9e1da44d84a4cfa5f9193109ff0310772592db (diff)
downloadmariadb-git-bb-10.4-svoj-MDEV-17441.tar.gz
-rw-r--r--storage/innobase/dict/dict0dict.cc141
-rw-r--r--storage/innobase/dict/dict0mem.cc5
-rw-r--r--storage/innobase/dict/dict0stats.cc43
-rw-r--r--storage/innobase/handler/ha_innodb.cc8
-rw-r--r--storage/innobase/handler/i_s.cc4
-rw-r--r--storage/innobase/include/dict0dict.h35
-rw-r--r--storage/innobase/include/dict0mem.h5
-rw-r--r--storage/innobase/include/dict0stats.ic6
8 files changed, 32 insertions, 215 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index d0d7924b30e..1435d57d6ac 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -268,145 +268,6 @@ dict_mutex_exit_for_mysql(void)
mutex_exit(&dict_sys->mutex);
}
-/** Allocate and init a dict_table_t's stats latch.
-This function must not be called concurrently on the same table object.
-@param[in,out] table_void table whose stats latch to create */
-static
-void
-dict_table_stats_latch_alloc(
- void* table_void)
-{
- dict_table_t* table = static_cast<dict_table_t*>(table_void);
-
- /* Note: rw_lock_create() will call the constructor */
-
- table->stats_latch = static_cast<rw_lock_t*>(
- ut_malloc_nokey(sizeof(rw_lock_t)));
-
- ut_a(table->stats_latch != NULL);
-
- rw_lock_create(dict_table_stats_key, table->stats_latch,
- SYNC_INDEX_TREE);
-}
-
-/** Deinit and free a dict_table_t's stats latch.
-This function must not be called concurrently on the same table object.
-@param[in,out] table table whose stats latch to free */
-static
-void
-dict_table_stats_latch_free(
- dict_table_t* table)
-{
- rw_lock_free(table->stats_latch);
- ut_free(table->stats_latch);
-}
-
-/** Create a dict_table_t's stats latch or delay for lazy creation.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to create
-@param[in] enabled if false then the latch is disabled
-and dict_table_stats_lock()/unlock() become noop on this table. */
-void
-dict_table_stats_latch_create(
- dict_table_t* table,
- bool enabled)
-{
- if (!enabled) {
- table->stats_latch = NULL;
- table->stats_latch_created = os_once::DONE;
- return;
- }
-
- /* We create this lazily the first time it is used. */
- table->stats_latch = NULL;
- table->stats_latch_created = os_once::NEVER_DONE;
-}
-
-/** Destroy a dict_table_t's stats latch.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to destroy */
-void
-dict_table_stats_latch_destroy(
- dict_table_t* table)
-{
- if (table->stats_latch_created == os_once::DONE
- && table->stats_latch != NULL) {
-
- dict_table_stats_latch_free(table);
- }
-}
-
-/** Lock the appropriate latch to protect a given table's statistics.
-@param[in] table table whose stats to lock
-@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
-void
-dict_table_stats_lock(
- dict_table_t* table,
- ulint latch_mode)
-{
- ut_ad(table != NULL);
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- os_once::do_or_wait_for_done(
- &table->stats_latch_created,
- dict_table_stats_latch_alloc, table);
-
- if (table->stats_latch == NULL) {
- /* This is a dummy table object that is private in the current
- thread and is not shared between multiple threads, thus we
- skip any locking. */
- return;
- }
-
- switch (latch_mode) {
- case RW_S_LATCH:
- rw_lock_s_lock(table->stats_latch);
- break;
- case RW_X_LATCH:
- rw_lock_x_lock(table->stats_latch);
- break;
- case RW_NO_LATCH:
- /* fall through */
- default:
- ut_error;
- }
-}
-
-/** Unlock the latch that has been locked by dict_table_stats_lock().
-@param[in] table table whose stats to unlock
-@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
-void
-dict_table_stats_unlock(
- dict_table_t* table,
- ulint latch_mode)
-{
- ut_ad(table != NULL);
- ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
-
- if (table->stats_latch == NULL) {
- /* This is a dummy table object that is private in the current
- thread and is not shared between multiple threads, thus we
- skip any locking. */
- return;
- }
-
- switch (latch_mode) {
- case RW_S_LATCH:
- rw_lock_s_unlock(table->stats_latch);
- break;
- case RW_X_LATCH:
- rw_lock_x_unlock(table->stats_latch);
- break;
- case RW_NO_LATCH:
- /* fall through */
- default:
- ut_error;
- }
-}
-
-
/** Open a persistent table.
@param[in] table_id persistent table identifier
@param[in] ignore_err errors to ignore
@@ -1227,6 +1088,7 @@ void dict_table_t::add_to_cache()
ulint fold = ut_fold_string(name.m_name);
mutex_create(LATCH_ID_AUTOINC, &autoinc_mutex);
+ rw_lock_create(dict_table_stats_key, &stats_latch, SYNC_INDEX_TREE);
/* Look for a table with the same name: error if such exists */
{
@@ -2012,6 +1874,7 @@ void dict_table_remove_from_cache(dict_table_t* table, bool lru, bool keep)
}
mutex_free(&table->autoinc_mutex);
+ rw_lock_free(&table->stats_latch);
if (!keep) {
dict_mem_table_free(table);
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index f42e845082b..04ba7b3446f 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -168,10 +168,6 @@ dict_mem_table_create(
table->v_cols = static_cast<dict_v_col_t*>(
mem_heap_alloc(heap, n_v_cols * sizeof(*table->v_cols)));
- /* true means that the stats latch will be enabled -
- dict_table_stats_lock() will not be noop. */
- dict_table_stats_latch_create(table, true);
-
table->autoinc_lock = static_cast<ib_lock_t*>(
mem_heap_alloc(heap, lock_get_size()));
@@ -212,7 +208,6 @@ dict_mem_table_free(
}
dict_mem_table_free_foreign_vcol_set(table);
- dict_table_stats_latch_destroy(table);
table->foreign_set.~dict_foreign_set();
table->referenced_set.~dict_foreign_set();
diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc
index 9492d9ed711..8fcba803a4a 100644
--- a/storage/innobase/dict/dict0stats.cc
+++ b/storage/innobase/dict/dict0stats.cc
@@ -418,11 +418,6 @@ dict_stats_table_clone_create(
t->corrupted = table->corrupted;
- /* This private object "t" is not shared with other threads, so
- we do not need the stats_latch (thus we pass false below). The
- dict_table_stats_lock()/unlock() routines will do nothing. */
- dict_table_stats_latch_create(t, false);
-
UT_LIST_INIT(t->indexes, &dict_index_t::indexes);
for (index = dict_table_get_first_index(table);
@@ -497,15 +492,13 @@ dict_stats_table_clone_free(
/*========================*/
dict_table_t* t) /*!< in: dummy table object to free */
{
- dict_table_stats_latch_destroy(t);
mem_heap_free(t->heap);
}
/*********************************************************************//**
Write all zeros (or 1 where it makes sense) into an index
statistics members. The resulting stats correspond to an empty index.
-The caller must own index's table stats latch in X mode
-(dict_table_stats_lock(table, RW_X_LATCH)) */
+The caller must own index's table stats latch in X mode */
static
void
dict_stats_empty_index(
@@ -547,7 +540,9 @@ dict_stats_empty_table(
{
/* Zero the stats members */
- dict_table_stats_lock(table, RW_X_LATCH);
+ if (table->cached) {
+ rw_lock_x_lock(&table->stats_latch);
+ }
table->stat_n_rows = 0;
table->stat_clustered_index_size = 1;
@@ -573,7 +568,9 @@ dict_stats_empty_table(
table->stat_initialized = TRUE;
- dict_table_stats_unlock(table, RW_X_LATCH);
+ if (table->cached) {
+ rw_lock_x_unlock(&table->stats_latch);
+ }
}
/*********************************************************************//**
@@ -789,7 +786,7 @@ dict_stats_snapshot_create(
{
mutex_enter(&dict_sys->mutex);
- dict_table_stats_lock(table, RW_S_LATCH);
+ rw_lock_s_lock(&table->stats_latch);
dict_stats_assert_initialized(table);
@@ -804,7 +801,7 @@ dict_stats_snapshot_create(
t->stats_sample_pages = table->stats_sample_pages;
t->stats_bg_flag = table->stats_bg_flag;
- dict_table_stats_unlock(table, RW_S_LATCH);
+ rw_lock_s_unlock(&table->stats_latch);
mutex_exit(&dict_sys->mutex);
@@ -2216,7 +2213,7 @@ dict_stats_update_persistent(
DEBUG_PRINTF("%s(table=%s)\n", __func__, table->name);
- dict_table_stats_lock(table, RW_X_LATCH);
+ rw_lock_x_lock(&table->stats_latch);
/* analyze the clustered index first */
@@ -2227,7 +2224,7 @@ dict_stats_update_persistent(
|| (index->type | DICT_UNIQUE) != (DICT_CLUSTERED | DICT_UNIQUE)) {
/* Table definition is corrupt */
- dict_table_stats_unlock(table, RW_X_LATCH);
+ rw_lock_x_unlock(&table->stats_latch);
dict_stats_empty_table(table, true);
return(DB_CORRUPTION);
@@ -2279,7 +2276,7 @@ dict_stats_update_persistent(
dict_stats_assert_initialized(table);
- dict_table_stats_unlock(table, RW_X_LATCH);
+ rw_lock_x_unlock(&table->stats_latch);
return(DB_SUCCESS);
}
@@ -3109,9 +3106,9 @@ dict_stats_update_for_index(
if (dict_stats_is_persistent_enabled(index->table)) {
if (dict_stats_persistent_storage_check(false)) {
- dict_table_stats_lock(index->table, RW_X_LATCH);
+ rw_lock_x_lock(&index->table->stats_latch);
dict_stats_analyze_index(index);
- dict_table_stats_unlock(index->table, RW_X_LATCH);
+ rw_lock_x_unlock(&index->table->stats_latch);
dict_stats_save(index->table, &index->id);
DBUG_VOID_RETURN;
}
@@ -3132,9 +3129,9 @@ dict_stats_update_for_index(
}
}
- dict_table_stats_lock(index->table, RW_X_LATCH);
+ rw_lock_x_lock(&index->table->stats_latch);
dict_stats_update_transient_for_index(index);
- dict_table_stats_unlock(index->table, RW_X_LATCH);
+ rw_lock_x_unlock(&index->table->stats_latch);
DBUG_VOID_RETURN;
}
@@ -3288,7 +3285,7 @@ dict_stats_update(
switch (err) {
case DB_SUCCESS:
- dict_table_stats_lock(table, RW_X_LATCH);
+ rw_lock_x_lock(&table->stats_latch);
/* Pass reset_ignored_indexes=true as parameter
to dict_stats_copy. This will cause statictics
@@ -3297,7 +3294,7 @@ dict_stats_update(
dict_stats_assert_initialized(table);
- dict_table_stats_unlock(table, RW_X_LATCH);
+ rw_lock_x_unlock(&table->stats_latch);
dict_stats_table_clone_free(t);
@@ -3352,11 +3349,11 @@ dict_stats_update(
transient:
- dict_table_stats_lock(table, RW_X_LATCH);
+ rw_lock_x_lock(&table->stats_latch);
dict_stats_update_transient(table);
- dict_table_stats_unlock(table, RW_X_LATCH);
+ rw_lock_x_unlock(&table->stats_latch);
return(DB_SUCCESS);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index f29d1cb098e..c6430818233 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -14002,7 +14002,7 @@ ha_innobase::info_low(
ulint stat_sum_of_other_index_sizes;
if (!(flag & HA_STATUS_NO_LOCK)) {
- dict_table_stats_lock(ib_table, RW_S_LATCH);
+ rw_lock_s_lock(&ib_table->stats_latch);
}
ut_a(ib_table->stat_initialized);
@@ -14016,7 +14016,7 @@ ha_innobase::info_low(
= ib_table->stat_sum_of_other_index_sizes;
if (!(flag & HA_STATUS_NO_LOCK)) {
- dict_table_stats_unlock(ib_table, RW_S_LATCH);
+ rw_lock_s_unlock(&ib_table->stats_latch);
}
/*
@@ -14120,7 +14120,7 @@ ha_innobase::info_low(
}
if (!(flag & HA_STATUS_NO_LOCK)) {
- dict_table_stats_lock(ib_table, RW_S_LATCH);
+ rw_lock_s_lock(&ib_table->stats_latch);
}
ut_a(ib_table->stat_initialized);
@@ -14202,7 +14202,7 @@ ha_innobase::info_low(
}
if (!(flag & HA_STATUS_NO_LOCK)) {
- dict_table_stats_unlock(ib_table, RW_S_LATCH);
+ rw_lock_s_unlock(&ib_table->stats_latch);
}
snprintf(path, sizeof(path), "%s/%s%s",
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 4016b11387e..20d02c574e8 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -6270,7 +6270,7 @@ i_s_dict_fill_sys_tablestats(
OK(field_store_string(fields[SYS_TABLESTATS_NAME],
table->name.m_name));
- dict_table_stats_lock(table, RW_S_LATCH);
+ rw_lock_s_lock(&table->stats_latch);
if (table->stat_initialized) {
OK(field_store_string(fields[SYS_TABLESTATS_INIT],
@@ -6300,7 +6300,7 @@ i_s_dict_fill_sys_tablestats(
OK(fields[SYS_TABLESTATS_MODIFIED]->store(0, true));
}
- dict_table_stats_unlock(table, RW_S_LATCH);
+ rw_lock_s_unlock(&table->stats_latch);
OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, true));
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index f0c99dc4064..bb830fbfae9 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -1366,41 +1366,6 @@ void
dict_mutex_exit_for_mysql(void);
/*===========================*/
-/** Create a dict_table_t's stats latch or delay for lazy creation.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to create
-@param[in] enabled if false then the latch is disabled
-and dict_table_stats_lock()/unlock() become noop on this table. */
-void
-dict_table_stats_latch_create(
- dict_table_t* table,
- bool enabled);
-
-/** Destroy a dict_table_t's stats latch.
-This function is only called from either single threaded environment
-or from a thread that has not shared the table object with other threads.
-@param[in,out] table table whose stats latch to destroy */
-void
-dict_table_stats_latch_destroy(
- dict_table_t* table);
-
-/** Lock the appropriate latch to protect a given table's statistics.
-@param[in] table table whose stats to lock
-@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
-void
-dict_table_stats_lock(
- dict_table_t* table,
- ulint latch_mode);
-
-/** Unlock the latch that has been locked by dict_table_stats_lock().
-@param[in] table table whose stats to unlock
-@param[in] latch_mode RW_S_LATCH or RW_X_LATCH */
-void
-dict_table_stats_unlock(
- dict_table_t* table,
- ulint latch_mode);
-
/********************************************************************//**
Checks if the database name in two table names is the same.
@return TRUE if same db name */
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 51adb9bf99e..6905149766a 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -1955,9 +1955,6 @@ public:
/** Statistics for query optimization. @{ */
- /** Creation state of 'stats_latch'. */
- volatile os_once::state_t stats_latch_created;
-
/** This latch protects:
dict_table_t::stat_initialized,
dict_table_t::stat_n_rows (*),
@@ -1969,7 +1966,7 @@ public:
dict_table_t::indexes*::stat_n_leaf_pages.
(*) Those are not always protected for
performance reasons. */
- rw_lock_t* stats_latch;
+ rw_lock_t stats_latch;
/** TRUE if statistics have been calculated the first time after
database startup or table creation. */
diff --git a/storage/innobase/include/dict0stats.ic b/storage/innobase/include/dict0stats.ic
index 4edc7860363..ad916327d90 100644
--- a/storage/innobase/include/dict0stats.ic
+++ b/storage/innobase/include/dict0stats.ic
@@ -178,10 +178,10 @@ dict_stats_deinit(
ut_a(table->get_ref_count() == 0);
- dict_table_stats_lock(table, RW_X_LATCH);
+ rw_lock_x_lock(&table->stats_latch);
if (!table->stat_initialized) {
- dict_table_stats_unlock(table, RW_X_LATCH);
+ rw_lock_x_unlock(&table->stats_latch);
return;
}
@@ -223,5 +223,5 @@ dict_stats_deinit(
}
#endif /* UNIV_DEBUG_VALGRIND */
- dict_table_stats_unlock(table, RW_X_LATCH);
+ rw_lock_x_unlock(&table->stats_latch);
}