3902 Mattias Jonsson 2012-05-24
bug#13838761
Reverting InnoDB part of WL#4305, which caused the regression.
rb 1089 approved by Jimmy
No easy/small test case have yet been found,
but I have verified that it does not crash after 30 min of sysqa
test as it does without this patch.
modified:
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.h
3901 Mayank Prasad 2012-05-25
Bug #14117145 SPURIOUS TEST FAILURES, TEST PERFORMANCE_SCHEMA.CONNECTION
Details:
- There were continuous disconnect statements one after another,
without synchronization. That was causing race conditions.
Fix:
- Wait for each disconnect to finish explicitly and then do
further disconnect.
modified:
mysql-test/suite/perfschema/include/connection_load.inc
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc revid:mayank.prasad@stripped
+++ b/storage/innobase/handler/ha_innodb.cc revid:mattias.jonsson@stripped
@@ -96,6 +96,9 @@ this program; if not, write to the Free
# ifndef MYSQL_PLUGIN_IMPORT
# define MYSQL_PLUGIN_IMPORT /* nothing */
# endif /* MYSQL_PLUGIN_IMPORT */
+
+/** to protect innobase_open_files */
+static mysql_mutex_t innobase_share_mutex;
/** to force correct commit order in binlog */
static ulong commit_threads = 0;
static mysql_mutex_t commit_threads_m;
@@ -231,6 +234,8 @@ it every INNOBASE_WAKE_INTERVAL'th step.
#define INNOBASE_WAKE_INTERVAL 32
static ulong innobase_active_counter = 0;
+static hash_table_t* innobase_open_tables;
+
/** Allowed values of innodb_change_buffering */
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
"none", /* IBUF_USE_NONE */
@@ -257,6 +262,7 @@ const struct _ft_vft_ext ft_vft_ext_resu
#ifdef HAVE_PSI_INTERFACE
/* Keys to register pthread mutexes/cond in the current file with
performance schema */
+static mysql_pfs_key_t innobase_share_mutex_key;
static mysql_pfs_key_t commit_threads_m_key;
static mysql_pfs_key_t commit_cond_mutex_key;
static mysql_pfs_key_t commit_cond_key;
@@ -264,6 +270,7 @@ static mysql_pfs_key_t commit_cond_key;
static PSI_mutex_info all_pthread_mutexes[] = {
{&commit_threads_m_key, "commit_threads_m", 0},
{&commit_cond_mutex_key, "commit_cond_mutex", 0},
+ {&innobase_share_mutex_key, "innobase_share_mutex", 0}
};
static PSI_cond_info all_innodb_conds[] = {
@@ -620,6 +627,23 @@ static SHOW_VAR innodb_status_variables[
{NullS, NullS, SHOW_LONG}
};
+/************************************************************************//**
+Handling the shared INNOBASE_SHARE structure that is needed to provide table
+locking. Register the table name if it doesn't exist in the hash table. */
+static
+INNOBASE_SHARE*
+get_share(
+/*======*/
+ const char* table_name); /*!< in: table to lookup */
+
+/************************************************************************//**
+Free the shared object that was registered with get_share(). */
+static
+void
+free_share(
+/*=======*/
+ INNOBASE_SHARE* share); /*!< in/own: share to free */
+
/*****************************************************************//**
Frees a possible InnoDB trx object associated with the current THD.
@return 0 or error number */
@@ -3088,6 +3112,10 @@ innobase_change_buffering_inited_ok:
ibuf_max_size_update(innobase_change_buffer_max_size);
+ innobase_open_tables = hash_create(200);
+ mysql_mutex_init(innobase_share_mutex_key,
+ &innobase_share_mutex,
+ MY_MUTEX_INIT_FAST);
mysql_mutex_init(commit_threads_m_key,
&commit_threads_m, MY_MUTEX_INIT_FAST);
mysql_mutex_init(commit_cond_mutex_key,
@@ -3146,11 +3174,14 @@ innobase_end(
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
innodb_inited = 0;
+ hash_table_free(innobase_open_tables);
+ innobase_open_tables = NULL;
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
err = 1;
}
srv_free_paths_and_sizes();
my_free(internal_innobase_data_file_path);
+ mysql_mutex_destroy(&innobase_share_mutex);
mysql_mutex_destroy(&commit_threads_m);
mysql_mutex_destroy(&commit_cond_m);
mysql_cond_destroy(&commit_cond);
@@ -4173,8 +4204,8 @@ innobase_match_index_columns(
}
/*******************************************************************//**
-This function builds a translation table in Innobase_share
-object for fast index location with mysql array number from its
+This function builds a translation table in INNOBASE_SHARE
+structure for fast index location with mysql array number from its
table->key_info structure. This also provides the necessary translation
between the key order in mysql key_info and Innodb ib_table->indexes if
they are not fully matched with each other.
@@ -4191,7 +4222,7 @@ innobase_build_index_translation(
dictionary */
dict_table_t* ib_table,/*!< in: table in Innodb data
dictionary */
- Innobase_share* share) /*!< in/out: share object
+ INNOBASE_SHARE* share) /*!< in/out: share structure
where index translation table
will be constructed in. */
{
@@ -4311,7 +4342,7 @@ static
dict_index_t*
innobase_index_lookup(
/*==================*/
- Innobase_share* share, /*!< in: share object for index
+ INNOBASE_SHARE* share, /*!< in: share structure for index
translation table. */
uint keynr) /*!< in: index number for the requested
index */
@@ -4466,7 +4497,7 @@ ha_innobase::open(
user_thd = NULL;
- if (!(share=get_share())) {
+ if (!(share=get_share(name))) {
DBUG_RETURN(1);
}
@@ -4579,6 +4610,7 @@ retry:
REFMAN "innodb-troubleshooting.html for how "
"you can resolve the problem.", norm_name);
+ free_share(share);
my_errno = ENOENT;
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
@@ -4623,6 +4655,7 @@ table_opened:
}
if (!thd_tablespace_op(thd) && no_tablespace) {
+ free_share(share);
my_errno = ENOENT;
dict_table_close(ib_table, FALSE, FALSE);
@@ -4858,6 +4891,8 @@ ha_innobase::close()
upd_buf_size = 0;
}
+ free_share(share);
+
MONITOR_INC(MONITOR_TABLE_CLOSE);
/* Tell InnoDB server that there might be work for
@@ -10163,7 +10198,7 @@ static
int
innobase_get_mysql_key_number_for_index(
/*====================================*/
- Innobase_share* share, /*!< in: share object for index
+ INNOBASE_SHARE* share, /*!< in: share structure for index
translation table. */
const TABLE* table, /*!< in: table in MySQL data
dictionary */
@@ -12143,31 +12178,94 @@ innobase_show_status(
}
/************************************************************************//**
-Handling the shared Innobase_share object that is needed to provide table
-locking. */
-Innobase_share*
-ha_innobase::get_share(void)
-/*========================*/
+Handling the shared INNOBASE_SHARE structure that is needed to provide table
+locking. Register the table name if it doesn't exist in the hash table. */
+static
+INNOBASE_SHARE*
+get_share(
+/*======*/
+ const char* table_name)
{
- Innobase_share *tmp_share;
+ INNOBASE_SHARE* share;
- lock_shared_ha_data();
- tmp_share= static_cast<Innobase_share*>(get_ha_share_ptr());
+ mysql_mutex_lock(&innobase_share_mutex);
- if (!tmp_share)
- {
- tmp_share= new Innobase_share;
- if (!tmp_share)
- {
- unlock_shared_ha_data();
- return(NULL);
- }
+ ulint fold = ut_fold_string(table_name);
+
+ HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
+ INNOBASE_SHARE*, share,
+ ut_ad(share->use_count > 0),
+ !strcmp(share->table_name, table_name));
+
+ if (!share) {
+
+ uint length = (uint) strlen(table_name);
+
+ /* TODO: invoke HASH_MIGRATE if innobase_open_tables
+ grows too big */
+
+ share = (INNOBASE_SHARE*) my_malloc(sizeof(*share)+length+1,
+ MYF(MY_FAE | MY_ZEROFILL));
+
+ share->table_name = (char*) memcpy(share + 1,
+ table_name, length + 1);
+
+ HASH_INSERT(INNOBASE_SHARE, table_name_hash,
+ innobase_open_tables, fold, share);
- set_ha_share_ptr(static_cast<Handler_share*>(tmp_share));
+ thr_lock_init(&share->lock);
+
+ /* Index translation table initialization */
+ share->idx_trans_tbl.index_mapping = NULL;
+ share->idx_trans_tbl.index_count = 0;
+ share->idx_trans_tbl.array_size = 0;
+ }
+
+ share->use_count++;
+ mysql_mutex_unlock(&innobase_share_mutex);
+
+ return(share);
+}
+
+/************************************************************************//**
+Free the shared object that was registered with get_share(). */
+static
+void
+free_share(
+/*=======*/
+ INNOBASE_SHARE* share) /*!< in/own: table share to free */
+{
+ mysql_mutex_lock(&innobase_share_mutex);
+
+#ifdef UNIV_DEBUG
+ INNOBASE_SHARE* share2;
+ ulint fold = ut_fold_string(share->table_name);
+
+ HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
+ INNOBASE_SHARE*, share2,
+ ut_ad(share->use_count > 0),
+ !strcmp(share->table_name, share2->table_name));
+
+ ut_a(share2 == share);
+#endif /* UNIV_DEBUG */
+
+ if (!--share->use_count) {
+ ulint fold = ut_fold_string(share->table_name);
+
+ HASH_DELETE(INNOBASE_SHARE, table_name_hash,
+ innobase_open_tables, fold, share);
+ thr_lock_delete(&share->lock);
+
+ /* Free any memory from index translation table */
+ my_free(share->idx_trans_tbl.index_mapping);
+
+ my_free(share);
+
+ /* TODO: invoke HASH_MIGRATE if innobase_open_tables
+ shrinks too much */
}
- unlock_shared_ha_data();
- ut_ad(tmp_share);
- return(tmp_share);
+
+ mysql_mutex_unlock(&innobase_share_mutex);
}
/*****************************************************************//**
=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h revid:mayank.prasad@stripped
+++ b/storage/innobase/handler/ha_innodb.h revid:mattias.jonsson@stripped
@@ -38,29 +38,19 @@ typedef struct innodb_idx_translate_stru
/** InnoDB table share */
-class Innobase_share : public Handler_share
-{
-public:
+typedef struct st_innobase_share {
THR_LOCK lock; /*!< MySQL lock protecting
this structure */
+ const char* table_name; /*!< InnoDB table name */
+ uint use_count; /*!< reference count,
+ incremented in get_share()
+ and decremented in
+ free_share() */
+ void* table_name_hash;/*!< hash table chain node */
innodb_idx_translate_t idx_trans_tbl; /*!< index translation
table between MySQL and
Innodb */
- Innobase_share()
- {
- thr_lock_init(&lock);
- idx_trans_tbl.index_mapping = NULL;
- idx_trans_tbl.index_count = 0;
- idx_trans_tbl.array_size = 0;
- }
- ~Innobase_share()
- {
- thr_lock_delete(&lock);
-
- /* Free any memory from index translation table */
- my_free(idx_trans_tbl.index_mapping);
- }
-};
+} INNOBASE_SHARE;
/** InnoDB B-tree index */
@@ -83,7 +73,7 @@ class ha_innobase: public handler
currently using the handle; this is
set in external_lock function */
THR_LOCK_DATA lock;
- Innobase_share* share; /*!< information for MySQL
+ INNOBASE_SHARE* share; /*!< information for MySQL
table locking */
uchar* upd_buf; /*!< buffer used in updates */
@@ -361,8 +351,6 @@ public:
private:
/** The multi range read session object */
DsMrr_impl ds_mrr;
- /** Connects/gets Innobase_share in TABLE_SHARE */
- Innobase_share* get_share();
/* @} */
};
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (mattias.jonsson:3901 to 3902) Bug#13838761WL#4305 | Mattias Jonsson | 27 May |