mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Partial fix for Bug#11764622 57480: MEMORY LEAK WHEN HAVING 256+ TABLES
Port vasil.dimov@oracle.com-20111205082756-wtlg8isyn4yohyny from mysql-trunk
This commit is contained in:
@@ -3816,9 +3816,8 @@ retry:
|
||||
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
|
||||
}
|
||||
|
||||
prebuilt = row_create_prebuilt(ib_table);
|
||||
prebuilt = row_create_prebuilt(ib_table, table->s->reclength);
|
||||
|
||||
prebuilt->mysql_row_len = table->s->reclength;
|
||||
prebuilt->default_rec = table->s->default_values;
|
||||
ut_ad(prebuilt->default_rec);
|
||||
|
||||
|
@@ -1008,7 +1008,12 @@ ha_innobase::final_add_index(
|
||||
row_prebuilt_free(prebuilt, TRUE);
|
||||
error = row_merge_drop_table(trx, old_table);
|
||||
add->indexed_table->n_mysql_handles_opened++;
|
||||
prebuilt = row_create_prebuilt(add->indexed_table);
|
||||
prebuilt = row_create_prebuilt(add->indexed_table,
|
||||
0 /* XXX Do we know the mysql_row_len here?
|
||||
Before the addition of this parameter to
|
||||
row_create_prebuilt() the mysql_row_len
|
||||
member was left 0 (from zalloc) in the
|
||||
prebuilt object. */);
|
||||
}
|
||||
|
||||
err = convert_error_code_to_mysql(
|
||||
|
@@ -231,6 +231,12 @@ dtuple_set_n_fields_cmp(
|
||||
dtuple_t* tuple, /*!< in: tuple */
|
||||
ulint n_fields_cmp); /*!< in: number of fields used in
|
||||
comparisons in rem0cmp.* */
|
||||
|
||||
/* Estimate the number of bytes that are going to be allocated when
|
||||
creating a new dtuple_t object */
|
||||
#define DTUPLE_EST_ALLOC(n_fields) \
|
||||
(sizeof(dtuple_t) + (n_fields) * sizeof(dfield_t))
|
||||
|
||||
/**********************************************************//**
|
||||
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.
|
||||
@@ -240,7 +246,8 @@ dtuple_t*
|
||||
dtuple_create(
|
||||
/*==========*/
|
||||
mem_heap_t* heap, /*!< in: memory heap where the tuple
|
||||
is created */
|
||||
is created, DTUPLE_EST_ALLOC(n_fields)
|
||||
bytes will be allocated from this heap */
|
||||
ulint n_fields); /*!< in: number of fields */
|
||||
|
||||
/**********************************************************//**
|
||||
|
@@ -356,15 +356,15 @@ dtuple_t*
|
||||
dtuple_create(
|
||||
/*==========*/
|
||||
mem_heap_t* heap, /*!< in: memory heap where the tuple
|
||||
is created */
|
||||
is created, DTUPLE_EST_ALLOC(n_fields)
|
||||
bytes will be allocated from this heap */
|
||||
ulint n_fields) /*!< in: number of fields */
|
||||
{
|
||||
dtuple_t* tuple;
|
||||
|
||||
ut_ad(heap);
|
||||
|
||||
tuple = (dtuple_t*) mem_heap_alloc(heap, sizeof(dtuple_t)
|
||||
+ n_fields * sizeof(dfield_t));
|
||||
tuple = (dtuple_t*) mem_heap_alloc(heap, DTUPLE_EST_ALLOC(n_fields));
|
||||
tuple->info_bits = 0;
|
||||
tuple->n_fields = n_fields;
|
||||
tuple->n_fields_cmp = n_fields;
|
||||
|
@@ -168,7 +168,9 @@ UNIV_INTERN
|
||||
row_prebuilt_t*
|
||||
row_create_prebuilt(
|
||||
/*================*/
|
||||
dict_table_t* table); /*!< in: Innobase table handle */
|
||||
dict_table_t* table, /*!< in: Innobase table handle */
|
||||
ulint mysql_row_len); /*!< in: length in bytes of a row in
|
||||
the MySQL format */
|
||||
/********************************************************************//**
|
||||
Free a prebuilt struct for a MySQL table handle. */
|
||||
UNIV_INTERN
|
||||
|
@@ -667,17 +667,60 @@ UNIV_INTERN
|
||||
row_prebuilt_t*
|
||||
row_create_prebuilt(
|
||||
/*================*/
|
||||
dict_table_t* table) /*!< in: Innobase table handle */
|
||||
dict_table_t* table, /*!< in: Innobase table handle */
|
||||
ulint mysql_row_len) /*!< in: length in bytes of a row in
|
||||
the MySQL format */
|
||||
{
|
||||
row_prebuilt_t* prebuilt;
|
||||
mem_heap_t* heap;
|
||||
dict_index_t* clust_index;
|
||||
dtuple_t* ref;
|
||||
ulint ref_len;
|
||||
ulint search_tuple_n_fields;
|
||||
|
||||
heap = mem_heap_create(sizeof *prebuilt + 128);
|
||||
search_tuple_n_fields = 2 * dict_table_get_n_cols(table);
|
||||
|
||||
prebuilt = mem_heap_zalloc(heap, sizeof *prebuilt);
|
||||
clust_index = dict_table_get_first_index(table);
|
||||
|
||||
/* Make sure that search_tuple is long enough for clustered index */
|
||||
ut_a(2 * dict_table_get_n_cols(table) >= clust_index->n_fields);
|
||||
|
||||
ref_len = dict_index_get_n_unique(clust_index);
|
||||
|
||||
#define PREBUILT_HEAP_INITIAL_SIZE \
|
||||
( \
|
||||
sizeof(*prebuilt) \
|
||||
/* allocd in this function */ \
|
||||
+ DTUPLE_EST_ALLOC(search_tuple_n_fields) \
|
||||
+ DTUPLE_EST_ALLOC(ref_len) \
|
||||
/* allocd in row_prebuild_sel_graph() */ \
|
||||
+ sizeof(sel_node_t) \
|
||||
+ sizeof(que_fork_t) \
|
||||
+ sizeof(que_thr_t) \
|
||||
/* allocd in row_get_prebuilt_update_vector() */ \
|
||||
+ sizeof(upd_node_t) \
|
||||
+ sizeof(upd_t) \
|
||||
+ sizeof(upd_field_t) \
|
||||
* dict_table_get_n_cols(table) \
|
||||
+ sizeof(que_fork_t) \
|
||||
+ sizeof(que_thr_t) \
|
||||
/* allocd in row_get_prebuilt_insert_row() */ \
|
||||
+ sizeof(ins_node_t) \
|
||||
/* mysql_row_len could be huge and we are not \
|
||||
sure if this prebuilt instance is going to be \
|
||||
used in inserts */ \
|
||||
+ (mysql_row_len < 256 ? mysql_row_len : 0) \
|
||||
+ DTUPLE_EST_ALLOC(dict_table_get_n_cols(table)) \
|
||||
+ sizeof(que_fork_t) \
|
||||
+ sizeof(que_thr_t) \
|
||||
)
|
||||
|
||||
/* We allocate enough space for the objects that are likely to
|
||||
be created later in order to minimize the number of malloc()
|
||||
calls */
|
||||
heap = mem_heap_create(PREBUILT_HEAP_INITIAL_SIZE);
|
||||
|
||||
prebuilt = mem_heap_zalloc(heap, sizeof(*prebuilt));
|
||||
|
||||
prebuilt->magic_n = ROW_PREBUILT_ALLOCATED;
|
||||
prebuilt->magic_n2 = ROW_PREBUILT_ALLOCATED;
|
||||
@@ -695,15 +738,7 @@ row_create_prebuilt(
|
||||
UNIV_MEM_INVALID(&prebuilt->stored_select_lock_type,
|
||||
sizeof prebuilt->stored_select_lock_type);
|
||||
|
||||
prebuilt->search_tuple = dtuple_create(
|
||||
heap, 2 * dict_table_get_n_cols(table));
|
||||
|
||||
clust_index = dict_table_get_first_index(table);
|
||||
|
||||
/* Make sure that search_tuple is long enough for clustered index */
|
||||
ut_a(2 * dict_table_get_n_cols(table) >= clust_index->n_fields);
|
||||
|
||||
ref_len = dict_index_get_n_unique(clust_index);
|
||||
prebuilt->search_tuple = dtuple_create(heap, search_tuple_n_fields);
|
||||
|
||||
ref = dtuple_create(heap, ref_len);
|
||||
|
||||
@@ -720,6 +755,8 @@ row_create_prebuilt(
|
||||
|
||||
prebuilt->autoinc_last_value = 0;
|
||||
|
||||
prebuilt->mysql_row_len = mysql_row_len;
|
||||
|
||||
return(prebuilt);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user