Commit a4fa485f authored by Vasil Dimov's avatar Vasil Dimov

Partial fix for Bug#11764622 57480: MEMORY LEAK WHEN HAVING 256+ TABLES

Port vasil.dimov@oracle.com-20111205082900-lx9om1joscejr25e from mysql-trunk
parent 93ab1d54
...@@ -2066,8 +2066,9 @@ static ...@@ -2066,8 +2066,9 @@ static
void void
dict_load_foreign_cols( dict_load_foreign_cols(
/*===================*/ /*===================*/
const char* id, /*!< in: foreign constraint id as a const char* id, /*!< in: foreign constraint id, not
null-terminated string */ necessary '\0'-terminated */
ulint id_len, /*!< in: id length */
dict_foreign_t* foreign)/*!< in: foreign constraint object */ dict_foreign_t* foreign)/*!< in: foreign constraint object */
{ {
dict_table_t* sys_foreign_cols; dict_table_t* sys_foreign_cols;
...@@ -2097,7 +2098,7 @@ dict_load_foreign_cols( ...@@ -2097,7 +2098,7 @@ dict_load_foreign_cols(
tuple = dtuple_create(foreign->heap, 1); tuple = dtuple_create(foreign->heap, 1);
dfield = dtuple_get_nth_field(tuple, 0); 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); dict_index_copy_types(tuple, sys_index, 1);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
...@@ -2110,7 +2111,7 @@ dict_load_foreign_cols( ...@@ -2110,7 +2111,7 @@ dict_load_foreign_cols(
ut_a(!rec_get_deleted_flag(rec, 0)); ut_a(!rec_get_deleted_flag(rec, 0));
field = rec_get_nth_field_old(rec, 0, &len); 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); ut_a(ut_memcmp(id, field, len) == 0);
field = rec_get_nth_field_old(rec, 1, &len); field = rec_get_nth_field_old(rec, 1, &len);
...@@ -2139,8 +2140,9 @@ static ...@@ -2139,8 +2140,9 @@ static
ulint ulint
dict_load_foreign( dict_load_foreign(
/*==============*/ /*==============*/
const char* id, /*!< in: foreign constraint id as a const char* id, /*!< in: foreign constraint id, not
null-terminated string */ necessary '\0'-terminated */
ulint id_len, /*!< in: id length */
ibool check_charsets, ibool check_charsets,
/*!< in: TRUE=check charset compatibility */ /*!< in: TRUE=check charset compatibility */
ibool check_recursive) ibool check_recursive)
...@@ -2176,7 +2178,7 @@ dict_load_foreign( ...@@ -2176,7 +2178,7 @@ dict_load_foreign(
tuple = dtuple_create(heap2, 1); tuple = dtuple_create(heap2, 1);
dfield = dtuple_get_nth_field(tuple, 0); 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); dict_index_copy_types(tuple, sys_index, 1);
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
...@@ -2188,8 +2190,8 @@ dict_load_foreign( ...@@ -2188,8 +2190,8 @@ dict_load_foreign(
/* Not found */ /* Not found */
fprintf(stderr, fprintf(stderr,
"InnoDB: Error A: cannot load foreign constraint %s\n", "InnoDB: Error A: cannot load foreign constraint "
id); "%.*s\n", (int) id_len, id);
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
...@@ -2201,11 +2203,11 @@ dict_load_foreign( ...@@ -2201,11 +2203,11 @@ dict_load_foreign(
field = rec_get_nth_field_old(rec, 0, &len); field = rec_get_nth_field_old(rec, 0, &len);
/* Check if the id in record is the searched one */ /* 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, fprintf(stderr,
"InnoDB: Error B: cannot load foreign constraint %s\n", "InnoDB: Error B: cannot load foreign constraint "
id); "%.*s\n", (int) id_len, id);
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
...@@ -2231,7 +2233,7 @@ dict_load_foreign( ...@@ -2231,7 +2233,7 @@ dict_load_foreign(
foreign->type = (unsigned int) (n_fields_and_type >> 24); foreign->type = (unsigned int) (n_fields_and_type >> 24);
foreign->n_fields = (unsigned int) (n_fields_and_type & 0x3FFUL); 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); field = rec_get_nth_field_old(rec, 3, &len);
...@@ -2247,7 +2249,7 @@ dict_load_foreign( ...@@ -2247,7 +2249,7 @@ dict_load_foreign(
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); 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( ref_table = dict_table_check_if_in_cache_low(
foreign->referenced_table_name_lookup); foreign->referenced_table_name_lookup);
...@@ -2326,8 +2328,8 @@ dict_load_foreigns( ...@@ -2326,8 +2328,8 @@ dict_load_foreigns(
ibool check_charsets) /*!< in: TRUE=check charset ibool check_charsets) /*!< in: TRUE=check charset
compatibility */ compatibility */
{ {
char tuple_buf[DTUPLE_EST_ALLOC(1)];
btr_pcur_t pcur; btr_pcur_t pcur;
mem_heap_t* heap;
dtuple_t* tuple; dtuple_t* tuple;
dfield_t* dfield; dfield_t* dfield;
dict_index_t* sec_index; dict_index_t* sec_index;
...@@ -2335,7 +2337,6 @@ dict_load_foreigns( ...@@ -2335,7 +2337,6 @@ dict_load_foreigns(
const rec_t* rec; const rec_t* rec;
const byte* field; const byte* field;
ulint len; ulint len;
char* id ;
ulint err; ulint err;
mtr_t mtr; mtr_t mtr;
...@@ -2362,9 +2363,8 @@ dict_load_foreigns( ...@@ -2362,9 +2363,8 @@ dict_load_foreigns(
sec_index = dict_table_get_next_index( sec_index = dict_table_get_next_index(
dict_table_get_first_index(sys_foreign)); dict_table_get_first_index(sys_foreign));
start_load: 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 = dtuple_get_nth_field(tuple, 0);
dfield_set_data(dfield, table_name, ut_strlen(table_name)); dfield_set_data(dfield, table_name, ut_strlen(table_name));
...@@ -2418,7 +2418,6 @@ loop: ...@@ -2418,7 +2418,6 @@ loop:
/* Now we get a foreign key constraint id */ /* Now we get a foreign key constraint id */
field = rec_get_nth_field_old(rec, 1, &len); field = rec_get_nth_field_old(rec, 1, &len);
id = mem_heap_strdupl(heap, (char*) field, len);
btr_pcur_store_position(&pcur, &mtr); btr_pcur_store_position(&pcur, &mtr);
...@@ -2426,11 +2425,11 @@ loop: ...@@ -2426,11 +2425,11 @@ loop:
/* Load the foreign constraint definition to the dictionary cache */ /* 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) { if (err != DB_SUCCESS) {
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mem_heap_free(heap);
return(err); return(err);
} }
...@@ -2446,7 +2445,6 @@ next_rec: ...@@ -2446,7 +2445,6 @@ next_rec:
load_next_index: load_next_index:
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap);
sec_index = dict_table_get_next_index(sec_index); sec_index = dict_table_get_next_index(sec_index);
......
...@@ -237,6 +237,20 @@ creating a new dtuple_t object */ ...@@ -237,6 +237,20 @@ creating a new dtuple_t object */
#define DTUPLE_EST_ALLOC(n_fields) \ #define DTUPLE_EST_ALLOC(n_fields) \
(sizeof(dtuple_t) + (n_fields) * sizeof(dfield_t)) (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 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. of fields used in record comparisons for this tuple is n_fields.
......
...@@ -348,23 +348,25 @@ dtuple_get_nth_field( ...@@ -348,23 +348,25 @@ dtuple_get_nth_field(
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/**********************************************************//** /**********************************************************//**
Creates a data tuple to a memory heap. The default value for number Creates a data tuple from an already allocated chunk of memory.
of fields used in record comparisons for this tuple is n_fields. The size of the chunk must be at least DTUPLE_EST_ALLOC(n_fields).
@return own: created tuple */ The default value for number of fields used in record comparisons
for this tuple is n_fields.
@return created tuple (inside buf) */
UNIV_INLINE UNIV_INLINE
dtuple_t* dtuple_t*
dtuple_create( dtuple_create_from_mem(
/*==========*/ /*===================*/
mem_heap_t* heap, /*!< in: memory heap where the tuple void* buf, /*!< in, out: buffer to use */
is created, DTUPLE_EST_ALLOC(n_fields) ulint buf_size, /*!< in: buffer size */
bytes will be allocated from this heap */
ulint n_fields) /*!< in: number of fields */ ulint n_fields) /*!< in: number of fields */
{ {
dtuple_t* tuple; 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->info_bits = 0;
tuple->n_fields = n_fields; tuple->n_fields = n_fields;
tuple->n_fields_cmp = n_fields; tuple->n_fields_cmp = n_fields;
...@@ -386,9 +388,38 @@ dtuple_create( ...@@ -386,9 +388,38 @@ dtuple_create(
dfield_get_type(field)->mtype = DATA_ERROR; 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); UNIV_MEM_INVALID(tuple->fields, n_fields * sizeof *tuple->fields);
#endif #endif
return(tuple); return(tuple);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment