From: Dmitry Lenev Date: May 17 2012 11:29am Subject: bzr push into mysql-trunk branch (Dmitry.Lenev:3900 to 3901) WL#5772 List-Archive: http://lists.mysql.com/commits/143843 Message-Id: <20120517112933.1CAE84206D3@jubjub> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3901 Dmitry Lenev 2012-05-17 WL#5772 "Add partitioned Table Definition Cache to avoid using LOCK_open and its derivatives in DML queries". Review change #12: - Changed Table_cache::free_table_all() not to use hash look up. modified: sql/sql_base.cc sql/sql_base.h 3900 Dmitry Lenev 2012-05-17 WL#5772 "Add partitioned Table Definition Cache to avoid using LOCK_open and its derivatives in DML queries". Review changes #11: - Removed wrong assert. - Fix some lines to better follow coding style. modified: sql/sql_base.cc === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2012-05-17 03:46:29 +0000 +++ b/sql/sql_base.cc 2012-05-17 11:14:28 +0000 @@ -9809,34 +9809,42 @@ void tdc_flush_unused_tables() @param thd Thread context @param remove_type Type of removal. @sa tdc_remove_table(). - @param key Key identifying table. - @param key_length Length of key. + @param share TABLE_SHARE for the table to be removed. @note Caller should own LOCK_open and locks on all table cache instances. */ void Table_cache::free_table_all(THD *thd, enum_tdc_remove_table_type remove_type, - const char *key, uint key_length) + TABLE_SHARE *share) { + Table_cache_element *cache_el[MAX_TABLE_CACHES]; + Table_cache::assert_owner_all_and_tdc(); + /* + Freeing last TABLE instance for the share will destroy the share + and corresponding TABLE_SHARE::cache_element[] array. To make + iteration over this array safe, even when share is destroyed in + the middle of iteration, we create copy of this array on the stack + and iterate over it. + */ + memcpy(&cache_el, share->cache_element, + table_cache_instances * sizeof(Table_cache_element *)); + for (uint i= 0; i < table_cache_instances; i++) { - Table_cache_element *el; - - if ((el= (Table_cache_element*)my_hash_search(&m_table_cache[i].m_cache, - (uchar*) key, key_length))) + if (cache_el[i]) { - Table_cache_element::TABLE_list::Iterator it(el->free_tables); + Table_cache_element::TABLE_list::Iterator it(cache_el[i]->free_tables); TABLE *table; #ifndef DBUG_OFF if (remove_type == TDC_RT_REMOVE_ALL) - DBUG_ASSERT(el->used_tables.is_empty()); + DBUG_ASSERT(cache_el[i]->used_tables.is_empty()); else if (remove_type == TDC_RT_REMOVE_NOT_OWN) { - Table_cache_element::TABLE_list::Iterator it2(el->used_tables); + Table_cache_element::TABLE_list::Iterator it2(cache_el[i]->used_tables); while ((table= it2++)) { if (table->in_use != thd) @@ -9921,7 +9929,7 @@ void tdc_remove_table(THD *thd, enum_tdc used. */ share->version= 0; - Table_cache::free_table_all(thd, remove_type, key, key_length); + Table_cache::free_table_all(thd, remove_type, share); } else (void) my_hash_delete(&table_def_cache, (uchar*) share); === modified file 'sql/sql_base.h' --- a/sql/sql_base.h 2012-05-16 07:52:08 +0000 +++ b/sql/sql_base.h 2012-05-17 11:14:28 +0000 @@ -738,7 +738,7 @@ public: static void free_table_all(THD *thd, enum_tdc_remove_table_type remove_type, - const char *key, uint key_length); + TABLE_SHARE *share); static void free_all_unused_tables(); No bundle (reason: useless for push emails).