From: vasil.dimov Date: June 22 2010 4:32pm Subject: bzr commit into mysql-5.1-innodb branch (vasil.dimov:3517) Bug#47991 List-Archive: http://lists.mysql.com/commits/111791 X-Bug: 47991 Message-Id: <20100622163253.A6C7D2E0AA@mail.v5d.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0540200321713705736==" --===============0540200321713705736== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///usr/local/devel/bzrroot/server/mysql-5.1-innodb/ based on revid:marko.makela@stripped 3517 Vasil Dimov 2010-06-22 Fix Bug#47991 InnoDB Dictionary Cache memory usage increases indefinitely when renaming tables Allocate the table name using ut_malloc() instead of table->heap because the latter cannot be freed. Adjust dict_sys->size calculations all over the code. Change dict_table_t::name from const char* to char* because we need to ut_malloc()/ut_free() it. Reviewed by: Inaam, Marko, Heikki (rb://384) Approved by: Heikki (rb://384) modified: storage/innodb_plugin/dict/dict0dict.c storage/innodb_plugin/dict/dict0mem.c storage/innodb_plugin/include/dict0mem.h storage/innodb_plugin/include/univ.i storage/innodb_plugin/page/page0zip.c storage/innodb_plugin/row/row0merge.c === modified file 'storage/innodb_plugin/dict/dict0dict.c' --- a/storage/innodb_plugin/dict/dict0dict.c revid:marko.makela@stripped +++ b/storage/innodb_plugin/dict/dict0dict.c revid:vasil.dimov@stripped @@ -850,7 +850,8 @@ dict_table_add_to_cache( /* Add table to LRU list of tables */ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); - dict_sys->size += mem_heap_get_size(table->heap); + dict_sys->size += mem_heap_get_size(table->heap) + + strlen(table->name) + 1; } /**********************************************************************//** @@ -904,14 +905,21 @@ dict_table_rename_in_cache( dict_foreign_t* foreign; dict_index_t* index; ulint fold; - ulint old_size; - const char* old_name; + char old_name[MAX_TABLE_NAME_LEN + 1]; ut_ad(table); ut_ad(mutex_own(&(dict_sys->mutex))); - old_size = mem_heap_get_size(table->heap); - old_name = table->name; + /* store the old/current name to an automatic variable */ + if (strlen(table->name) + 1 <= sizeof(old_name)) { + memcpy(old_name, table->name, strlen(table->name) + 1); + } else { + ut_print_timestamp(stderr); + fprintf(stderr, "InnoDB: too long table name: '%s', " + "max length is %d\n", table->name, + MAX_TABLE_NAME_LEN); + ut_error; + } fold = ut_fold_string(new_name); @@ -957,12 +965,22 @@ dict_table_rename_in_cache( /* Remove table from the hash tables of tables */ HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, ut_fold_string(old_name), table); - table->name = mem_heap_strdup(table->heap, new_name); + + if (strlen(new_name) > strlen(table->name)) { + /* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid + memory fragmentation, we assume a repeated calls of + ut_realloc() with the same size do not cause fragmentation */ + ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN); + table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1); + } + memcpy(table->name, new_name, strlen(new_name) + 1); /* Add table to hash table of tables */ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); - dict_sys->size += (mem_heap_get_size(table->heap) - old_size); + + dict_sys->size += strlen(new_name) - strlen(old_name); + ut_a(dict_sys->size > 0); /* Update the table_name field in indexes */ index = dict_table_get_first_index(table); @@ -1187,7 +1205,7 @@ dict_table_remove_from_cache( /* Remove table from LRU list of tables */ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); - size = mem_heap_get_size(table->heap); + size = mem_heap_get_size(table->heap) + strlen(table->name) + 1; ut_ad(dict_sys->size >= size); === modified file 'storage/innodb_plugin/dict/dict0mem.c' --- a/storage/innodb_plugin/dict/dict0mem.c revid:marko.makela@stripped +++ b/storage/innodb_plugin/dict/dict0mem.c revid:vasil.dimov@stripped @@ -68,7 +68,8 @@ dict_mem_table_create( table->heap = heap; table->flags = (unsigned int) flags; - table->name = mem_heap_strdup(heap, name); + table->name = ut_malloc(strlen(name) + 1); + memcpy(table->name, name, strlen(name) + 1); table->space = (unsigned int) space; table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS); @@ -106,6 +107,7 @@ dict_mem_table_free( #ifndef UNIV_HOTBACKUP mutex_free(&(table->autoinc_mutex)); #endif /* UNIV_HOTBACKUP */ + ut_free(table->name); mem_heap_free(table->heap); } === modified file 'storage/innodb_plugin/include/dict0mem.h' --- a/storage/innodb_plugin/include/dict0mem.h revid:marko.makela@stripped +++ b/storage/innodb_plugin/include/dict0mem.h revid:vasil.dimov@stripped @@ -382,7 +382,7 @@ initialized to 0, NULL or FALSE in dict_ struct dict_table_struct{ dulint id; /*!< id of the table */ mem_heap_t* heap; /*!< memory heap */ - const char* name; /*!< table name */ + char* name; /*!< table name */ const char* dir_path_of_temp_table;/*!< NULL or the directory path where a TEMPORARY table that was explicitly created by a user should be placed if === modified file 'storage/innodb_plugin/include/univ.i' --- a/storage/innodb_plugin/include/univ.i revid:marko.makela@stripped +++ b/storage/innodb_plugin/include/univ.i revid:vasil.dimov@stripped @@ -290,6 +290,12 @@ management to ensure correct alignment f /* Maximum number of parallel threads in a parallelized operation */ #define UNIV_MAX_PARALLELISM 32 +/* The maximum length of a table name. This is the MySQL limit and is +defined in mysql_com.h like NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN, the +number does not include a terminating '\0'. InnoDB probably can handle +longer names internally */ +#define MAX_TABLE_NAME_LEN 192 + /* UNIVERSAL TYPE DEFINITIONS ========================== === modified file 'storage/innodb_plugin/page/page0zip.c' --- a/storage/innodb_plugin/page/page0zip.c revid:marko.makela@stripped +++ b/storage/innodb_plugin/page/page0zip.c revid:vasil.dimov@stripped @@ -1464,6 +1464,7 @@ page_zip_fields_free( dict_table_t* table = index->table; mem_heap_free(index->heap); mutex_free(&(table->autoinc_mutex)); + ut_free(table->name); mem_heap_free(table->heap); } } === modified file 'storage/innodb_plugin/row/row0merge.c' --- a/storage/innodb_plugin/row/row0merge.c revid:marko.makela@stripped +++ b/storage/innodb_plugin/row/row0merge.c revid:vasil.dimov@stripped @@ -2336,7 +2336,7 @@ row_merge_rename_tables( { ulint err = DB_ERROR; pars_info_t* info; - const char* old_name= old_table->name; + char old_name[MAX_TABLE_NAME_LEN + 1]; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(old_table != new_table); @@ -2344,6 +2344,17 @@ row_merge_rename_tables( ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); + /* store the old/current name to an automatic variable */ + if (strlen(old_table->name) + 1 <= sizeof(old_name)) { + memcpy(old_name, old_table->name, strlen(old_table->name) + 1); + } else { + ut_print_timestamp(stderr); + fprintf(stderr, "InnoDB: too long table name: '%s', " + "max length is %d\n", old_table->name, + MAX_TABLE_NAME_LEN); + ut_error; + } + trx->op_info = "renaming tables"; /* We use the private SQL parser of Innobase to generate the query --===============0540200321713705736== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/vasil.dimov@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: vasil.dimov@stripped # target_branch: file:///usr/local/devel/bzrroot/server/mysql-5.1-\ # innodb/ # testament_sha1: 7ed8a765e27c822118e387b0ee516e49718eb641 # timestamp: 2010-06-22 19:32:53 +0300 # source_branch: bzr+ssh://bk/bzrroot/server/mysql-5.1-innodb/ # base_revision_id: marko.makela@stripped\ # 8g73k8k68dpj080u # # Begin bundle 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 AsVAuhfSsfz8dlKF9D/F3JFOFCQsimNXwA== --===============0540200321713705736==--