diff options
author | Sergey Vojtovich <svoj@mariadb.org> | 2019-06-13 16:04:47 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@mariadb.org> | 2019-06-13 16:04:47 +0400 |
commit | b10f66ea18100e55a3afe53659f8fcc9a7eb05c8 (patch) | |
tree | 37cdc5f341a92a85105ed5d7d0e52ddeeda054d1 | |
parent | ef9e1da44d84a4cfa5f9193109ff0310772592db (diff) | |
download | mariadb-git-bb-10.4-svoj-MDEV-17441.tar.gz |
-rw-r--r-- | storage/innobase/dict/dict0dict.cc | 141 | ||||
-rw-r--r-- | storage/innobase/dict/dict0mem.cc | 5 | ||||
-rw-r--r-- | storage/innobase/dict/dict0stats.cc | 43 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 8 | ||||
-rw-r--r-- | storage/innobase/handler/i_s.cc | 4 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.h | 35 | ||||
-rw-r--r-- | storage/innobase/include/dict0mem.h | 5 | ||||
-rw-r--r-- | storage/innobase/include/dict0stats.ic | 6 |
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); } |