mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 11:57:38 +02:00
Merge from mysql-5.1-innodb:
------------------------------------------------------------ revno: 3430 revision-id: vasil.dimov@oracle.com-20100428103452-6btsq4xv6v1etb5b parent: vasil.dimov@oracle.com-20100428103200-vs5nzx245sv2qy7n committer: Vasil Dimov <vasil.dimov@oracle.com> branch nick: mysql-5.1-innodb timestamp: Wed 2010-04-28 13:34:52 +0300 message: Bug#53046 dict_update_statistics_low can still be run concurrently on same table Followup to vasil.dimov@oracle.com-20100428102033-dt3caf531rs3lidr : Add more asserions, which I forgot. modified: storage/innodb_plugin/dict/dict0dict.c 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fdict%2Fdict0dict.c ------------------------------------------------------------ revno: 3429 revision-id: vasil.dimov@oracle.com-20100428103200-vs5nzx245sv2qy7n parent: vasil.dimov@oracle.com-20100428102033-dt3caf531rs3lidr committer: Vasil Dimov <vasil.dimov@oracle.com> branch nick: mysql-5.1-innodb timestamp: Wed 2010-04-28 13:32:00 +0300 message: Revert the fix of Bug#38996 Race condition in ANALYZE TABLE This is branches/zip@r6032 in SVN and _is part_ of revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6113 in BZR. This is being reverted because now the code is serialized directly on index->stat_n_diff_key_vals[] as the fix for Bug#53046 dict_update_statistics_low can still be run concurrently on same table goes. modified: storage/innodb_plugin/handler/ha_innodb.cc 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fhandler%2Fha_innodb.cc ------------------------------------------------------------ revno: 3428 revision-id: vasil.dimov@oracle.com-20100428102033-dt3caf531rs3lidr parent: vasil.dimov@oracle.com-20100428084627-wtrmc66wqvjsdgj7 committer: Vasil Dimov <vasil.dimov@oracle.com> branch nick: mysql-5.1-innodb timestamp: Wed 2010-04-28 13:20:33 +0300 message: Followup to vasil.dimov@oracle.com-20100428084627-wtrmc66wqvjsdgj7: Address Marko's suggestions wrt the fix of Bug#53046 dict_update_statistics_low can still be run concurrently on same table modified: storage/innodb_plugin/dict/dict0dict.c 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fdict%2Fdict0dict.c ------------------------------------------------------------ revno: 3427 revision-id: vasil.dimov@oracle.com-20100428084627-wtrmc66wqvjsdgj7 parent: mmakela@bk-internal.mysql.com-20100428063325-irts4ze9et5bsqdq committer: Vasil Dimov <vasil.dimov@oracle.com> branch nick: mysql-5.1-innodb timestamp: Wed 2010-04-28 11:46:27 +0300 message: Fix Bug#53046 dict_update_statistics_low can still be run concurrently on same table Protect dict_index_t::stat_n_diff_key_vals[] with an array of mutexes. Testing: tested all code paths under UNIV_SYNC_DEBUG for the one in dict_print() one has to enable the InnoDB table monitor: CREATE TABLE innodb_table_monitor (a int) ENGINE=INNODB; modified: storage/innodb_plugin/btr/btr0cur.c 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fbtr%2Fbtr0cur.c storage/innodb_plugin/dict/dict0dict.c 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fdict%2Fdict0dict.c storage/innodb_plugin/handler/ha_innodb.cc 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Fhandler%2Fha_innodb.cc storage/innodb_plugin/include/dict0dict.h 2@16c675df-0fcb-4bc9-8058-dcc011a37293:trunk%2Finclude%2Fdict0dict.h ------------------------------------------------------------
This commit is contained in:
parent
c3ea5056e4
commit
32aef81ec4
4 changed files with 85 additions and 11 deletions
|
|
@ -3477,6 +3477,8 @@ btr_estimate_number_of_different_key_vals(
|
|||
also the pages used for external storage of fields (those pages are
|
||||
included in index->stat_n_leaf_pages) */
|
||||
|
||||
dict_index_stat_mutex_enter(index);
|
||||
|
||||
for (j = 0; j <= n_cols; j++) {
|
||||
index->stat_n_diff_key_vals[j]
|
||||
= ((n_diff[j]
|
||||
|
|
@ -3506,6 +3508,8 @@ btr_estimate_number_of_different_key_vals(
|
|||
index->stat_n_diff_key_vals[j] += add_on;
|
||||
}
|
||||
|
||||
dict_index_stat_mutex_exit(index);
|
||||
|
||||
mem_free(n_diff);
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ UNIV_INTERN mysql_pfs_key_t dict_foreign_err_mutex_key;
|
|||
/** 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.
|
||||
|
|
@ -250,6 +254,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
|
||||
|
|
@ -616,6 +659,8 @@ void
|
|||
dict_init(void)
|
||||
/*===========*/
|
||||
{
|
||||
int i;
|
||||
|
||||
dict_sys = mem_alloc(sizeof(dict_sys_t));
|
||||
|
||||
mutex_create(dict_sys_mutex_key, &dict_sys->mutex, SYNC_DICT);
|
||||
|
|
@ -638,6 +683,10 @@ dict_init(void)
|
|||
|
||||
mutex_create(dict_foreign_err_mutex_key,
|
||||
&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);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
|
|
@ -4185,9 +4234,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
|
||||
|
|
@ -4365,6 +4418,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];
|
||||
|
|
@ -4372,6 +4427,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)) {
|
||||
|
|
@ -4867,5 +4924,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 */
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ static ulong commit_threads = 0;
|
|||
static mysql_mutex_t commit_threads_m;
|
||||
static mysql_cond_t commit_cond;
|
||||
static mysql_mutex_t commit_cond_m;
|
||||
static mysql_mutex_t analyze_mutex;
|
||||
static bool innodb_inited = 0;
|
||||
|
||||
#define INSIDE_HA_INNOBASE_CC
|
||||
|
|
@ -213,7 +212,6 @@ static mysql_pfs_key_t commit_cond_mutex_key;
|
|||
static mysql_pfs_key_t commit_cond_key;
|
||||
|
||||
static PSI_mutex_info all_pthread_mutexes[] = {
|
||||
{&analyze_mutex_key, "analyze_mutex", 0},
|
||||
{&commit_threads_m_key, "commit_threads_m", 0},
|
||||
{&commit_cond_mutex_key, "commit_cond_mutex", 0},
|
||||
{&innobase_share_mutex_key, "innobase_share_mutex", 0},
|
||||
|
|
@ -2430,8 +2428,6 @@ innobase_change_buffering_inited_ok:
|
|||
&commit_threads_m, MY_MUTEX_INIT_FAST);
|
||||
mysql_mutex_init(commit_cond_mutex_key,
|
||||
&commit_cond_m, MY_MUTEX_INIT_FAST);
|
||||
mysql_mutex_init(analyze_mutex_key,
|
||||
&analyze_mutex, MY_MUTEX_INIT_FAST);
|
||||
mysql_cond_init(commit_cond_key, &commit_cond, NULL);
|
||||
innodb_inited= 1;
|
||||
#ifdef MYSQL_DYNAMIC_PLUGIN
|
||||
|
|
@ -2486,7 +2482,6 @@ innobase_end(
|
|||
mysql_mutex_destroy(&prepare_commit_mutex);
|
||||
mysql_mutex_destroy(&commit_threads_m);
|
||||
mysql_mutex_destroy(&commit_cond_m);
|
||||
mysql_mutex_destroy(&analyze_mutex);
|
||||
mysql_cond_destroy(&commit_cond);
|
||||
}
|
||||
|
||||
|
|
@ -7801,6 +7796,8 @@ ha_innobase::info(
|
|||
break;
|
||||
}
|
||||
|
||||
dict_index_stat_mutex_enter(index);
|
||||
|
||||
if (index->stat_n_diff_key_vals[j + 1] == 0) {
|
||||
|
||||
rec_per_key = stats.records;
|
||||
|
|
@ -7809,6 +7806,8 @@ ha_innobase::info(
|
|||
index->stat_n_diff_key_vals[j + 1]);
|
||||
}
|
||||
|
||||
dict_index_stat_mutex_exit(index);
|
||||
|
||||
/* Since MySQL seems to favor table scans
|
||||
too much over index searches, we pretend
|
||||
index selectivity is 2 times better than
|
||||
|
|
@ -7863,15 +7862,9 @@ ha_innobase::analyze(
|
|||
THD* thd, /*!< in: connection thread handle */
|
||||
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
|
||||
{
|
||||
/* Serialize ANALYZE TABLE inside InnoDB, see
|
||||
Bug#38996 Race condition in ANALYZE TABLE */
|
||||
mysql_mutex_lock(&analyze_mutex);
|
||||
|
||||
/* Simply call ::info() with all the flags */
|
||||
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
|
||||
|
||||
mysql_mutex_unlock(&analyze_mutex);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1061,6 +1061,22 @@ UNIV_INTERN
|
|||
void
|
||||
dict_mutex_exit_for_mysql(void);
|
||||
/*===========================*/
|
||||
/**********************************************************************//**
|
||||
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 */
|
||||
/**********************************************************************//**
|
||||
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 */
|
||||
/********************************************************************//**
|
||||
Checks if the database name in two table names is the same.
|
||||
@return TRUE if same db name */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue