Skip to content
Permalink
Browse files

MDEV-17441 InnoDB transition to C++11 atomics

dict_table_t::stats_latch_created: remove along with related stuff

dict_table_t::stats_latch: make value member, not pointer. And always lock this
for simplicity, even to stats cloned table.

based on the work of Sergey Vojtovich
  • Loading branch information...
kevgs committed Jun 22, 2019
1 parent e9a5f28 commit 52a5097764a35a6cd1d185958afeef443901577a
@@ -226,145 +226,6 @@ dict_get_db_name_len(
return ulint(s - name);
}

/** 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
@@ -171,10 +171,6 @@ dict_mem_table_create(
new (&table->v_cols[i]) dict_v_col_t();
}

/* 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()));

@@ -190,6 +186,9 @@ dict_mem_table_create(
new(&table->foreign_set) dict_foreign_set();
new(&table->referenced_set) dict_foreign_set();

rw_lock_create(dict_table_stats_key, &table->stats_latch,
SYNC_INDEX_TREE);

return(table);
}

@@ -215,7 +214,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();
@@ -231,6 +229,8 @@ dict_mem_table_free(

UT_DELETE(table->s_cols);

rw_lock_free(&table->stats_latch);

mem_heap_free(table->heap);
}

@@ -33,6 +33,7 @@ Created Jan 06, 2010 Vasil Dimov
#include "pars0pars.h"
#include <mysql_com.h>
#include "btr0btr.h"
#include "sync0sync.h"

#include <algorithm>
#include <map>
@@ -417,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);
@@ -484,6 +480,8 @@ dict_stats_table_clone_create(

ut_d(t->magic_n = DICT_TABLE_MAGIC_N);

rw_lock_create(dict_table_stats_key, &t->stats_latch, SYNC_INDEX_TREE);

return(t);
}

@@ -496,15 +494,13 @@ dict_stats_table_clone_free(
/*========================*/
dict_table_t* t) /*!< in: dummy table object to free */
{
dict_table_stats_latch_destroy(t);
rw_lock_free(&t->stats_latch);
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)) */
statistics members. The resulting stats correspond to an empty index. */
static
void
dict_stats_empty_index(
@@ -515,6 +511,7 @@ dict_stats_empty_index(
{
ut_ad(!(index->type & DICT_FTS));
ut_ad(!dict_index_is_ibuf(index));
ut_ad(rw_lock_own(&index->table->stats_latch, RW_LOCK_X));

ulint n_uniq = index->n_uniq;

@@ -546,7 +543,7 @@ dict_stats_empty_table(
{
/* Zero the stats members */

dict_table_stats_lock(table, RW_X_LATCH);
rw_lock_x_lock(&table->stats_latch);

table->stat_n_rows = 0;
table->stat_clustered_index_size = 1;
@@ -572,7 +569,7 @@ dict_stats_empty_table(

table->stat_initialized = TRUE;

dict_table_stats_unlock(table, RW_X_LATCH);
rw_lock_x_unlock(&table->stats_latch);
}

/*********************************************************************//**
@@ -788,7 +785,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);

@@ -803,7 +800,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);

@@ -2215,7 +2212,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 */

@@ -2226,7 +2223,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);
@@ -2278,7 +2275,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);
}
@@ -3097,11 +3094,11 @@ 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);
index->table->stat_sum_of_other_index_sizes
+= index->stat_index_size;
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;
}
@@ -3122,9 +3119,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;
}
@@ -3278,7 +3275,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
@@ -3287,7 +3284,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);

@@ -3342,11 +3339,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);
}
@@ -14000,7 +14000,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);
@@ -14014,7 +14014,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);
}

/*
@@ -14118,7 +14118,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);
@@ -14200,7 +14200,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",

0 comments on commit 52a5097

Please sign in to comment.
You can’t perform that action at this time.