summaryrefslogtreecommitdiff
path: root/storage/innodb_plugin/dict/dict0dict.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innodb_plugin/dict/dict0dict.c')
-rw-r--r--storage/innodb_plugin/dict/dict0dict.c83
1 files changed, 75 insertions, 8 deletions
diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c
index 2e524a5a2e3..83438231689 100644
--- a/storage/innodb_plugin/dict/dict0dict.c
+++ b/storage/innodb_plugin/dict/dict0dict.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
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
@@ -80,6 +80,10 @@ UNIV_INTERN rw_lock_t dict_operation_lock;
/** Identifies generated InnoDB foreign key names */
static char dict_ibfk[] = "_ibfk_";
+/** array of mutexes protecting dict_index_t::stat_n_diff_key_vals[] */
+#define DICT_INDEX_STAT_MUTEX_SIZE 32
+mutex_t dict_index_stat_mutex[DICT_INDEX_STAT_MUTEX_SIZE];
+
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index.
@@ -140,7 +144,7 @@ static
void
dict_field_print_low(
/*=================*/
- dict_field_t* field); /*!< in: field */
+ const dict_field_t* field); /*!< in: field */
/*********************************************************************//**
Frees a foreign key struct. */
static
@@ -239,6 +243,45 @@ dict_mutex_exit_for_mysql(void)
mutex_exit(&(dict_sys->mutex));
}
+/** Get the mutex that protects index->stat_n_diff_key_vals[] */
+#define GET_INDEX_STAT_MUTEX(index) \
+ (&dict_index_stat_mutex[ut_fold_dulint(index->id) \
+ % DICT_INDEX_STAT_MUTEX_SIZE])
+
+/**********************************************************************//**
+Lock the appropriate mutex to protect index->stat_n_diff_key_vals[].
+index->id is used to pick the right mutex and it should not change
+before dict_index_stat_mutex_exit() is called on this index. */
+UNIV_INTERN
+void
+dict_index_stat_mutex_enter(
+/*========================*/
+ const dict_index_t* index) /*!< in: index */
+{
+ ut_ad(index != NULL);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+ ut_ad(index->cached);
+ ut_ad(!index->to_be_dropped);
+
+ mutex_enter(GET_INDEX_STAT_MUTEX(index));
+}
+
+/**********************************************************************//**
+Unlock the appropriate mutex that protects index->stat_n_diff_key_vals[]. */
+UNIV_INTERN
+void
+dict_index_stat_mutex_exit(
+/*=======================*/
+ const dict_index_t* index) /*!< in: index */
+{
+ ut_ad(index != NULL);
+ ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
+ ut_ad(index->cached);
+ ut_ad(!index->to_be_dropped);
+
+ mutex_exit(GET_INDEX_STAT_MUTEX(index));
+}
+
/********************************************************************//**
Decrements the count of open MySQL handles to a table. */
UNIV_INTERN
@@ -605,6 +648,8 @@ void
dict_init(void)
/*===========*/
{
+ int i;
+
dict_sys = mem_alloc(sizeof(dict_sys_t));
mutex_create(&dict_sys->mutex, SYNC_DICT);
@@ -625,6 +670,10 @@ dict_init(void)
ut_a(dict_foreign_err_file);
mutex_create(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
+
+ for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
+ mutex_create(&dict_index_stat_mutex[i], SYNC_INDEX_TREE);
+ }
}
/**********************************************************************//**
@@ -1460,6 +1509,7 @@ dict_index_add_to_cache(
if (!dict_index_find_cols(table, index)) {
+ dict_mem_index_free(index);
return(DB_CORRUPTION);
}
@@ -4170,9 +4220,13 @@ dict_update_statistics_low(
index = dict_table_get_first_index(table);
+ dict_index_stat_mutex_enter(index);
+
table->stat_n_rows = index->stat_n_diff_key_vals[
dict_index_get_n_unique(index)];
+ dict_index_stat_mutex_exit(index);
+
table->stat_clustered_index_size = index->stat_index_size;
table->stat_sum_of_other_index_sizes = sum_of_index_sizes
@@ -4350,6 +4404,8 @@ dict_index_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
+ dict_index_stat_mutex_enter(index);
+
if (index->n_user_defined_cols > 0) {
n_vals = index->stat_n_diff_key_vals[
index->n_user_defined_cols];
@@ -4357,6 +4413,8 @@ dict_index_print_low(
n_vals = index->stat_n_diff_key_vals[1];
}
+ dict_index_stat_mutex_exit(index);
+
if (dict_index_is_clust(index)) {
type_string = "clustered index";
} else if (dict_index_is_unique(index)) {
@@ -4402,7 +4460,7 @@ static
void
dict_field_print_low(
/*=================*/
- dict_field_t* field) /*!< in: field */
+ const dict_field_t* field) /*!< in: field */
{
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -4766,8 +4824,10 @@ UNIV_INTERN
void
dict_table_check_for_dup_indexes(
/*=============================*/
- const dict_table_t* table) /*!< in: Check for dup indexes
+ const dict_table_t* table, /*!< in: Check for dup indexes
in this table */
+ ibool tmp_ok) /*!< in: TRUE=allow temporary
+ index names */
{
/* Check for duplicates, ignoring indexes that are marked
as to be dropped */
@@ -4775,13 +4835,17 @@ dict_table_check_for_dup_indexes(
const dict_index_t* index1;
const dict_index_t* index2;
+ ut_ad(mutex_own(&dict_sys->mutex));
+
/* The primary index _must_ exist */
ut_a(UT_LIST_GET_LEN(table->indexes) > 0);
index1 = UT_LIST_GET_FIRST(table->indexes);
- index2 = UT_LIST_GET_NEXT(indexes, index1);
- while (index1 && index2) {
+ do {
+ ut_ad(tmp_ok || *index1->name != TEMP_INDEX_PREFIX);
+
+ index2 = UT_LIST_GET_NEXT(indexes, index1);
while (index2) {
@@ -4793,8 +4857,7 @@ dict_table_check_for_dup_indexes(
}
index1 = UT_LIST_GET_NEXT(indexes, index1);
- index2 = UT_LIST_GET_NEXT(indexes, index1);
- }
+ } while (index1);
}
#endif /* UNIV_DEBUG */
@@ -4847,5 +4910,9 @@ dict_close(void)
mem_free(dict_sys);
dict_sys = NULL;
+
+ for (i = 0; i < DICT_INDEX_STAT_MUTEX_SIZE; i++) {
+ mutex_free(&dict_index_stat_mutex[i]);
+ }
}
#endif /* !UNIV_HOTBACKUP */