Commit ddb360c7 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 ff5aef3a
......@@ -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 @@ dict_load_foreigns(
/* 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 @@ dict_load_foreigns(
/* 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 @@ dict_load_foreigns(
load_next_index:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
mem_heap_free(heap);
sec_index = dict_table_get_next_index(sec_index);
......
......@@ -237,6 +237,20 @@ creating a new dtuple_t object */
#define DTUPLE_EST_ALLOC(n_fields) \
(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.
......
......@@ -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);
}
......
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