Partial fix for Bug#11764622 57480: MEMORY LEAK WHEN HAVING 256+ TABLES
Port vasil.dimov@oracle.com-20111205082900-lx9om1joscejr25e from mysql-trunk
This commit is contained in:
parent
93ab1d547d
commit
a4fa485f5f
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user