90
90
/** Identifies generated InnoDB foreign key names */
91
91
static char dict_ibfk[] = "_ibfk_";
93
/** array of mutexes protecting dict_index_t::stat_n_diff_key_vals[] */
94
#define DICT_INDEX_STAT_MUTEX_SIZE 32
95
static mutex_t dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE];
93
/** array of rw locks protecting
94
dict_table_t::stat_initialized
95
dict_table_t::stat_n_rows (*)
96
dict_table_t::stat_clustered_index_size
97
dict_table_t::stat_sum_of_other_index_sizes
98
dict_table_t::stat_modified_counter (*)
99
dict_table_t::indexes*::stat_n_diff_key_vals[]
100
dict_table_t::indexes*::stat_index_size
101
dict_table_t::indexes*::stat_n_leaf_pages
102
(*) those are not always protected for performance reasons */
103
#define DICT_TABLE_STATS_LATCHES_SIZE 64
104
static rw_lock_t dict_table_stats_latches[DICT_TABLE_STATS_LATCHES_SIZE];
97
106
/*******************************************************************//**
98
107
Tries to find column names for the index and sets the col field of the
253
262
mutex_exit(&(dict_sys->mutex));
256
/** Get the mutex that protects index->stat_n_diff_key_vals[] */
257
#define GET_INDEX_STAT_MUTEX(index) \
258
(&dict_index_stat_mutex[ut_fold_ull(index->id) \
259
% DICT_INDEX_STAT_MUTEX_SIZE])
265
/** Get the latch that protects the stats of a given table */
266
#define GET_TABLE_STATS_LATCH(table) \
267
(&dict_table_stats_latches[ut_fold_ull(table->id) \
268
% DICT_TABLE_STATS_LATCHES_SIZE])
261
270
/**********************************************************************//**
262
Lock the appropriate mutex to protect index->stat_n_diff_key_vals[].
263
index->id is used to pick the right mutex and it should not change
264
before dict_index_stat_mutex_exit() is called on this index. */
271
Lock the appropriate latch to protect a given table's statistics.
272
table->id is used to pick the corresponding latch from a global array of
267
dict_index_stat_mutex_enter(
268
/*========================*/
269
const dict_index_t* index) /*!< in: index */
276
dict_table_stats_lock(
277
/*==================*/
278
const dict_table_t* table, /*!< in: table */
279
ulint latch_mode) /*!< in: RW_S_LATCH or
271
ut_ad(index != NULL);
272
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
273
ut_ad(index->cached);
274
ut_ad(!index->to_be_dropped);
282
ut_ad(table != NULL);
283
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
276
mutex_enter(GET_INDEX_STAT_MUTEX(index));
285
switch (latch_mode) {
287
rw_lock_s_lock(GET_TABLE_STATS_LATCH(table));
290
rw_lock_x_lock(GET_TABLE_STATS_LATCH(table));
279
299
/**********************************************************************//**
280
Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */
300
Unlock the latch that has been locked by dict_table_stats_lock() */
283
dict_index_stat_mutex_exit(
284
/*=======================*/
285
const dict_index_t* index) /*!< in: index */
303
dict_table_stats_unlock(
304
/*====================*/
305
const dict_table_t* table, /*!< in: table */
306
ulint latch_mode) /*!< in: RW_S_LATCH or
287
ut_ad(index != NULL);
288
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
289
ut_ad(index->cached);
290
ut_ad(!index->to_be_dropped);
309
ut_ad(table != NULL);
310
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
292
mutex_exit(GET_INDEX_STAT_MUTEX(index));
312
switch (latch_mode) {
314
rw_lock_s_unlock(GET_TABLE_STATS_LATCH(table));
317
rw_lock_x_unlock(GET_TABLE_STATS_LATCH(table));
295
326
/********************************************************************//**
680
711
mutex_create(dict_foreign_err_mutex_key,
681
712
&dict_foreign_err_mutex, SYNC_ANY_LATCH);
683
for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
684
mutex_create(PFS_NOT_INSTRUMENTED,
685
&dict_index_stat_mutex[i], SYNC_INDEX_TREE);
714
for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) {
715
rw_lock_create(PFS_NOT_INSTRUMENTED,
716
&dict_table_stats_latches[i], SYNC_INDEX_TREE);
689
720
/**********************************************************************//**
713
744
mutex_exit(&(dict_sys->mutex));
715
746
if (table != NULL) {
716
if (!table->stat_initialized) {
717
/* If table->ibd_file_missing == TRUE, this will
718
print an error message and return without doing
720
dict_update_statistics(table);
747
/* If table->ibd_file_missing == TRUE, this will
748
print an error message and return without doing
750
dict_update_statistics(table, TRUE /* only update stats
751
if they have not been initialized */);
3451
3481
start_of_latest_foreign);
3452
3482
mutex_exit(&dict_foreign_err_mutex);
3454
return(DB_CANNOT_ADD_CONSTRAINT);
3484
return(DB_CHILD_NO_INDEX);
3456
3486
ptr = dict_accept(cs, ptr, "REFERENCES", &success);
4196
4226
are used in query optimization. */
4199
dict_update_statistics_low(
4200
/*=======================*/
4229
dict_update_statistics(
4230
/*===================*/
4201
4231
dict_table_t* table, /*!< in/out: table */
4202
ibool has_dict_mutex __attribute__((unused)))
4203
/*!< in: TRUE if the caller has the
4232
ibool only_calc_if_missing_stats)/*!< in: only
4233
update/recalc the stats if they have
4234
not been initialized yet, otherwise
4206
4237
dict_index_t* index;
4207
4238
ulint sum_of_index_sizes = 0;
4275
4312
index = dict_table_get_first_index(table);
4277
dict_index_stat_mutex_enter(index);
4279
4314
table->stat_n_rows = index->stat_n_diff_key_vals[
4280
4315
dict_index_get_n_unique(index)];
4282
dict_index_stat_mutex_exit(index);
4284
4317
table->stat_clustered_index_size = index->stat_index_size;
4286
4319
table->stat_sum_of_other_index_sizes = sum_of_index_sizes
4289
4322
table->stat_initialized = TRUE;
4291
4324
table->stat_modified_counter = 0;
4294
/*********************************************************************//**
4295
Calculates new estimates for table and index statistics. The statistics
4296
are used in query optimization. */
4299
dict_update_statistics(
4300
/*===================*/
4301
dict_table_t* table) /*!< in/out: table */
4303
dict_update_statistics_low(table, FALSE);
4326
dict_table_stats_unlock(table, RW_X_LATCH);
4306
4329
/**********************************************************************//**
4381
4404
ut_ad(mutex_own(&(dict_sys->mutex)));
4383
dict_update_statistics_low(table, TRUE);
4406
dict_update_statistics(table, FALSE /* update even if initialized */);
4408
dict_table_stats_lock(table, RW_S_LATCH);
4385
4410
fprintf(stderr,
4386
4411
"--------------------------------------\n"
4809
4832
dict_table_replace_index_in_foreign_list(
4810
4833
/*=====================================*/
4811
4834
dict_table_t* table, /*!< in/out: table */
4812
dict_index_t* index) /*!< in: index to be replaced */
4835
dict_index_t* index, /*!< in: index to be replaced */
4836
const trx_t* trx) /*!< in: transaction handle */
4814
4838
dict_foreign_t* foreign;
4820
4844
if (foreign->foreign_index == index) {
4821
4845
dict_index_t* new_index
4822
4846
= dict_foreign_find_equiv_index(foreign);
4848
/* There must exist an alternative index if
4849
check_foreigns (FOREIGN_KEY_CHECKS) is on,
4850
since ha_innobase::prepare_drop_index had done
4851
the check before we reach here. */
4853
ut_a(new_index || !trx->check_foreigns);
4825
4855
foreign->foreign_index = new_index;