diff options
author | Vasil Dimov <vasil.dimov@oracle.com> | 2011-12-29 16:14:45 +0200 |
---|---|---|
committer | Vasil Dimov <vasil.dimov@oracle.com> | 2011-12-29 16:14:45 +0200 |
commit | 371ebdbb0357b3d586033131b7c9c69298d2ebd2 (patch) | |
tree | e4b6c35959af4a4f257a8e69ab059a2dd9584fff /storage | |
parent | 40848aa1c4fec718aacb185742741ac8ef95ff26 (diff) | |
download | mariadb-git-371ebdbb0357b3d586033131b7c9c69298d2ebd2.tar.gz |
Partial fix for Bug#11764622 57480: MEMORY LEAK WHEN HAVING 256+ TABLES
Port vasil.dimov@oracle.com-20111205082900-lx9om1joscejr25e from mysql-trunk
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/dict/dict0load.c | 42 | ||||
-rw-r--r-- | storage/innobase/include/data0data.h | 14 | ||||
-rw-r--r-- | storage/innobase/include/data0data.ic | 53 |
3 files changed, 76 insertions, 33 deletions
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index e13cc1b31f1..9828326dde1 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -2066,8 +2066,9 @@ static void dict_load_foreign_cols( /*===================*/ - const char* id, /*!< in: foreign constraint id as a - null-terminated string */ + const char* id, /*!< in: foreign constraint id, not + necessary '\0'-terminated */ + ulint id_len, /*!< in: id length */ dict_foreign_t* foreign)/*!< in: foreign constraint object */ { dict_table_t* sys_foreign_cols; @@ -2097,7 +2098,7 @@ dict_load_foreign_cols( tuple = dtuple_create(foreign->heap, 1); dfield = dtuple_get_nth_field(tuple, 0); - dfield_set_data(dfield, id, ut_strlen(id)); + dfield_set_data(dfield, id, id_len); dict_index_copy_types(tuple, sys_index, 1); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, @@ -2110,7 +2111,7 @@ dict_load_foreign_cols( ut_a(!rec_get_deleted_flag(rec, 0)); field = rec_get_nth_field_old(rec, 0, &len); - ut_a(len == ut_strlen(id)); + ut_a(len == id_len); ut_a(ut_memcmp(id, field, len) == 0); field = rec_get_nth_field_old(rec, 1, &len); @@ -2139,8 +2140,9 @@ static ulint dict_load_foreign( /*==============*/ - const char* id, /*!< in: foreign constraint id as a - null-terminated string */ + const char* id, /*!< in: foreign constraint id, not + necessary '\0'-terminated */ + ulint id_len, /*!< in: id length */ ibool check_charsets, /*!< in: TRUE=check charset compatibility */ ibool check_recursive) @@ -2176,7 +2178,7 @@ dict_load_foreign( tuple = dtuple_create(heap2, 1); dfield = dtuple_get_nth_field(tuple, 0); - dfield_set_data(dfield, id, ut_strlen(id)); + dfield_set_data(dfield, id, id_len); dict_index_copy_types(tuple, sys_index, 1); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, @@ -2188,8 +2190,8 @@ dict_load_foreign( /* Not found */ fprintf(stderr, - "InnoDB: Error A: cannot load foreign constraint %s\n", - id); + "InnoDB: Error A: cannot load foreign constraint " + "%.*s\n", (int) id_len, id); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -2201,11 +2203,11 @@ dict_load_foreign( field = rec_get_nth_field_old(rec, 0, &len); /* Check if the id in record is the searched one */ - if (len != ut_strlen(id) || ut_memcmp(id, field, len) != 0) { + if (len != id_len || ut_memcmp(id, field, len) != 0) { fprintf(stderr, - "InnoDB: Error B: cannot load foreign constraint %s\n", - id); + "InnoDB: Error B: cannot load foreign constraint " + "%.*s\n", (int) id_len, id); btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -2231,7 +2233,7 @@ dict_load_foreign( foreign->type = (unsigned int) (n_fields_and_type >> 24); foreign->n_fields = (unsigned int) (n_fields_and_type & 0x3FFUL); - foreign->id = mem_heap_strdup(foreign->heap, id); + foreign->id = mem_heap_strdupl(foreign->heap, id, id_len); field = rec_get_nth_field_old(rec, 3, &len); @@ -2247,7 +2249,7 @@ dict_load_foreign( btr_pcur_close(&pcur); mtr_commit(&mtr); - dict_load_foreign_cols(id, foreign); + dict_load_foreign_cols(id, id_len, foreign); ref_table = dict_table_check_if_in_cache_low( foreign->referenced_table_name_lookup); @@ -2326,8 +2328,8 @@ dict_load_foreigns( ibool check_charsets) /*!< in: TRUE=check charset compatibility */ { + char tuple_buf[DTUPLE_EST_ALLOC(1)]; btr_pcur_t pcur; - mem_heap_t* heap; dtuple_t* tuple; dfield_t* dfield; dict_index_t* sec_index; @@ -2335,7 +2337,6 @@ dict_load_foreigns( const rec_t* rec; const byte* field; ulint len; - char* id ; ulint err; mtr_t mtr; @@ -2362,9 +2363,8 @@ dict_load_foreigns( sec_index = dict_table_get_next_index( dict_table_get_first_index(sys_foreign)); start_load: - heap = mem_heap_create(256); - tuple = dtuple_create(heap, 1); + tuple = dtuple_create_from_mem(tuple_buf, sizeof(tuple_buf), 1); dfield = dtuple_get_nth_field(tuple, 0); dfield_set_data(dfield, table_name, ut_strlen(table_name)); @@ -2418,7 +2418,6 @@ loop: /* Now we get a foreign key constraint id */ field = rec_get_nth_field_old(rec, 1, &len); - id = mem_heap_strdupl(heap, (char*) field, len); btr_pcur_store_position(&pcur, &mtr); @@ -2426,11 +2425,11 @@ loop: /* Load the foreign constraint definition to the dictionary cache */ - err = dict_load_foreign(id, check_charsets, check_recursive); + err = dict_load_foreign((char*) field, len, check_charsets, + check_recursive); if (err != DB_SUCCESS) { btr_pcur_close(&pcur); - mem_heap_free(heap); return(err); } @@ -2446,7 +2445,6 @@ next_rec: load_next_index: btr_pcur_close(&pcur); mtr_commit(&mtr); - mem_heap_free(heap); sec_index = dict_table_get_next_index(sec_index); diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index 9435169a0fd..6d3c2988fdc 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -238,6 +238,20 @@ creating a new dtuple_t object */ (sizeof(dtuple_t) + (n_fields) * sizeof(dfield_t)) /**********************************************************//** +Creates a data tuple from an already allocated chunk of memory. +The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields). +The default value for number of fields used in record comparisons +for this tuple is n_fields. +@return created tuple (inside buf) */ +UNIV_INLINE +dtuple_t* +dtuple_create_from_mem( +/*===================*/ + void* buf, /*!< in, out: buffer to use */ + ulint buf_size, /*!< in: buffer size */ + ulint n_fields); /*!< in: number of fields */ + +/**********************************************************//** Creates a data tuple to a memory heap. The default value for number of fields used in record comparisons for this tuple is n_fields. @return own: created tuple */ diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic index 971f58412c0..205fa397987 100644 --- a/storage/innobase/include/data0data.ic +++ b/storage/innobase/include/data0data.ic @@ -348,23 +348,25 @@ dtuple_get_nth_field( #endif /* UNIV_DEBUG */ /**********************************************************//** -Creates a data tuple to a memory heap. The default value for number -of fields used in record comparisons for this tuple is n_fields. -@return own: created tuple */ +Creates a data tuple from an already allocated chunk of memory. +The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields). +The default value for number of fields used in record comparisons +for this tuple is n_fields. +@return created tuple (inside buf) */ UNIV_INLINE dtuple_t* -dtuple_create( -/*==========*/ - mem_heap_t* heap, /*!< in: memory heap where the tuple - is created, DTUPLE_EST_ALLOC(n_fields) - bytes will be allocated from this heap */ - ulint n_fields) /*!< in: number of fields */ +dtuple_create_from_mem( +/*===================*/ + void* buf, /*!< in, out: buffer to use */ + ulint buf_size, /*!< in: buffer size */ + ulint n_fields) /*!< in: number of fields */ { dtuple_t* tuple; - ut_ad(heap); + ut_ad(buf != NULL); + ut_a(buf_size >= DTUPLE_EST_ALLOC(n_fields)); - tuple = (dtuple_t*) mem_heap_alloc(heap, DTUPLE_EST_ALLOC(n_fields)); + tuple = (dtuple_t*) buf; tuple->info_bits = 0; tuple->n_fields = n_fields; tuple->n_fields_cmp = n_fields; @@ -386,9 +388,38 @@ dtuple_create( dfield_get_type(field)->mtype = DATA_ERROR; } } +#endif + return(tuple); +} + +/**********************************************************//** +Creates a data tuple to a memory heap. The default value for number +of fields used in record comparisons for this tuple is n_fields. +@return own: created tuple */ +UNIV_INLINE +dtuple_t* +dtuple_create( +/*==========*/ + mem_heap_t* heap, /*!< in: memory heap where the tuple + is created, DTUPLE_EST_ALLOC(n_fields) + bytes will be allocated from this heap */ + ulint n_fields) /*!< in: number of fields */ +{ + void* buf; + ulint buf_size; + dtuple_t* tuple; + + ut_ad(heap); + buf_size = DTUPLE_EST_ALLOC(n_fields); + buf = mem_heap_alloc(heap, buf_size); + + tuple = dtuple_create_from_mem(buf, buf_size, n_fields); + +#ifdef UNIV_DEBUG UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields); #endif + return(tuple); } |