Commit 487677d0 authored by marko's avatar marko

Merge r1264 from branches/zip: Avoid memory fragmentation when

adding column definitions to tables.

dict_mem_table_add_col(): Add the parameter "heap" for temporary memory
allocation.  Allow it and "name" to be NULL.  These parameters are NULL
when creating dummy indexes.

dict_add_col_name(): Remove calls to ut_malloc() and ut_free().

dict_table_get_col_name(): Allow table->col_names to be NULL.

dict_table_add_system_columns(), dict_table_add_to_cache():
Add the parameter "heap".
---
Additional changes that had to be merged from branches/zip:

dict_table_add_system_columns(): New function, factored out from
dict_table_add_to_cache().

mlog_parse_index(): Add some consistency checks, and make use of
dict_table_add_system_columns().
parent f3a8c1a6
......@@ -211,6 +211,7 @@ dict_boot(void)
dict_table_t* table;
dict_index_t* index;
dict_hdr_t* dict_hdr;
mem_heap_t* heap;
mtr_t mtr;
mtr_start(&mtr);
......@@ -218,6 +219,8 @@ dict_boot(void)
/* Create the hash tables etc. */
dict_init();
heap = mem_heap_create(450);
mutex_enter(&(dict_sys->mutex));
/* Get the dictionary header */
......@@ -244,19 +247,20 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "N_COLS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "MIX_LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "CLUSTER_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
table->id = DICT_TABLES_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_tables = table;
mem_heap_empty(heap);
index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
DICT_HDR_SPACE,
......@@ -283,18 +287,19 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "MTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "PRTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "PREC", DATA_INT, 0, 4);
table->id = DICT_COLUMNS_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_columns = table;
mem_heap_empty(heap);
index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
DICT_HDR_SPACE,
......@@ -311,13 +316,13 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "N_FIELDS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4);
/* The '+ 2' below comes from the 2 system fields */
#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
......@@ -331,8 +336,9 @@ dict_boot(void)
#endif
table->id = DICT_INDEXES_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_indexes = table;
mem_heap_empty(heap);
index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
DICT_HDR_SPACE,
......@@ -349,13 +355,14 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0);
table->id = DICT_FIELDS_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_fields = table;
mem_heap_free(heap);
index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
DICT_HDR_SPACE,
......
......@@ -960,7 +960,7 @@ dict_create_table_step(
if (node->state == TABLE_ADD_TO_CACHE) {
dict_table_add_to_cache(node->table);
dict_table_add_to_cache(node->table, node->heap);
err = DB_SUCCESS;
}
......
......@@ -410,10 +410,11 @@ dict_table_get_col_name(
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
s = table->col_names;
if (s) {
for (i = 0; i < col_nr; i++) {
s += strlen(s) + 1;
}
}
return(s);
}
......@@ -788,28 +789,18 @@ dict_table_get(
}
/**************************************************************************
Adds a table object to the dictionary cache. */
Adds system columns to a table object. */
void
dict_table_add_to_cache(
/*====================*/
dict_table_t* table) /* in: table */
dict_table_add_system_columns(
/*==========================*/
dict_table_t* table, /* in/out: table */
mem_heap_t* heap) /* in: temporary heap */
{
ulint fold;
ulint id_fold;
ulint i;
ulint row_len;
ut_ad(table);
ut_ad(mutex_own(&(dict_sys->mutex)));
ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(table->cached == FALSE);
fold = ut_fold_string(table->name);
id_fold = ut_fold_dulint(table->id);
table->cached = TRUE;
ut_ad(!table->cached);
/* NOTE: the system columns MUST be added in the following order
(so that they can be indexed by the numerical value of DATA_ROW_ID,
......@@ -817,19 +808,19 @@ dict_table_add_to_cache(
The clustered index will not always physically contain all
system columns. */
dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS,
dict_mem_table_add_col(table, heap, "DB_ROW_ID", DATA_SYS,
DATA_ROW_ID | DATA_NOT_NULL,
DATA_ROW_ID_LEN);
#if DATA_ROW_ID != 0
#error "DATA_ROW_ID != 0"
#endif
dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS,
dict_mem_table_add_col(table, heap, "DB_TRX_ID", DATA_SYS,
DATA_TRX_ID | DATA_NOT_NULL,
DATA_TRX_ID_LEN);
#if DATA_TRX_ID != 1
#error "DATA_TRX_ID != 1"
#endif
dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS,
dict_mem_table_add_col(table, heap, "DB_ROLL_PTR", DATA_SYS,
DATA_ROLL_PTR | DATA_NOT_NULL,
DATA_ROLL_PTR_LEN);
#if DATA_ROLL_PTR != 2
......@@ -841,10 +832,34 @@ dict_table_add_to_cache(
#if DATA_N_SYS_COLS != 3
#error "DATA_N_SYS_COLS != 3"
#endif
}
/**************************************************************************
Adds a table object to the dictionary cache. */
void
dict_table_add_to_cache(
/*====================*/
dict_table_t* table, /* in: table */
mem_heap_t* heap) /* in: temporary heap */
{
ulint fold;
ulint id_fold;
ulint i;
ulint row_len;
/* The lower limit for what we consider a "big" row */
#define BIG_ROW_SIZE 1024
ut_ad(mutex_own(&(dict_sys->mutex)));
dict_table_add_system_columns(table, heap);
table->cached = TRUE;
fold = ut_fold_string(table->name);
id_fold = ut_fold_dulint(table->id);
row_len = 0;
for (i = 0; i < table->n_def; i++) {
ulint col_len = dict_col_get_max_size(
......
......@@ -423,7 +423,8 @@ dict_load_columns(
ut_a(name_of_col_is(sys_columns, sys_index, 8, "PREC"));
dict_mem_table_add_col(table, name, mtype, prtype, col_len);
dict_mem_table_add_col(table, heap, name,
mtype, prtype, col_len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
......@@ -746,7 +747,7 @@ dict_load_table(
ut_ad(mutex_own(&(dict_sys->mutex)));
heap = mem_heap_create(1000);
heap = mem_heap_create(32000);
mtr_start(&mtr);
......@@ -852,7 +853,9 @@ dict_load_table(
dict_load_columns(table, heap);
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
mem_heap_empty(heap);
dict_load_indexes(table, heap);
......
......@@ -113,18 +113,11 @@ dict_mem_table_free(
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
mutex_free(&(table->autoinc_mutex));
if (table->col_names && (table->n_def < table->n_cols)) {
ut_free((void*)table->col_names);
}
mem_heap_free(table->heap);
}
/********************************************************************
Add 'name' to end of the col_names array (see dict_table_t::col_names). Call
ut_free on col_names (if not NULL), allocate new array (if heap, from it,
otherwise with ut_malloc), and copy col_names + name to it. */
Append 'name' to 'col_names' (@see dict_table_t::col_names). */
static
const char*
dict_add_col_name(
......@@ -134,21 +127,19 @@ dict_add_col_name(
NULL */
ulint cols, /* in: number of existing columns */
const char* name, /* in: new column name */
mem_heap_t* heap) /* in: heap, or NULL */
mem_heap_t* heap) /* in: heap */
{
ulint i;
ulint old_len;
ulint new_len;
ulint total_len;
const char* s;
char* res;
ut_a(((cols == 0) && !col_names) || ((cols > 0) && col_names));
ut_a(*name);
ut_ad(!cols == !col_names);
/* Find out length of existing array. */
if (col_names) {
s = col_names;
const char* s = col_names;
ulint i;
for (i = 0; i < cols; i++) {
s += strlen(s) + 1;
......@@ -162,11 +153,7 @@ dict_add_col_name(
new_len = strlen(name) + 1;
total_len = old_len + new_len;
if (heap) {
res = mem_heap_alloc(heap, total_len);
} else {
res = ut_malloc(total_len);
}
if (old_len > 0) {
memcpy(res, col_names, old_len);
......@@ -174,10 +161,6 @@ dict_add_col_name(
memcpy(res + old_len, name, new_len);
if (col_names) {
ut_free((char*)col_names);
}
return(res);
}
......@@ -188,7 +171,8 @@ void
dict_mem_table_add_col(
/*===================*/
dict_table_t* table, /* in: table */
const char* name, /* in: column name */
mem_heap_t* heap, /* in: temporary memory heap, or NULL */
const char* name, /* in: column name, or NULL */
ulint mtype, /* in: main datatype */
ulint prtype, /* in: precise type */
ulint len) /* in: precision */
......@@ -196,21 +180,32 @@ dict_mem_table_add_col(
dict_col_t* col;
ulint mbminlen;
ulint mbmaxlen;
mem_heap_t* heap;
ulint i;
ut_ad(table && name);
ut_ad(table);
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
ut_ad(!heap == !name);
table->n_def++;
i = table->n_def++;
if (name) {
if (UNIV_UNLIKELY(table->n_def == table->n_cols)) {
heap = table->heap;
}
if (UNIV_LIKELY(i) && UNIV_UNLIKELY(!table->col_names)) {
/* All preceding column names are empty. */
char* s = mem_heap_alloc(heap, table->n_def);
memset(s, 0, table->n_def);
table->col_names = s;
}
heap = table->n_def < table->n_cols ? NULL : table->heap;
table->col_names = dict_add_col_name(table->col_names,
table->n_def - 1,
name, heap);
i, name, heap);
}
col = (dict_col_t*) dict_table_get_nth_col(table, table->n_def - 1);
col = (dict_col_t*) dict_table_get_nth_col(table, i);
col->ind = table->n_def - 1;
col->ind = i;
col->ord_part = 0;
col->mtype = (unsigned int) mtype;
......@@ -323,7 +318,7 @@ dict_mem_index_add_field(
{
dict_field_t* field;
ut_ad(index && name);
ut_ad(index);
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
index->n_def++;
......
......@@ -4760,7 +4760,7 @@ create_table_def(
}
}
dict_mem_table_add_col(table,
dict_mem_table_add_col(table, table->heap,
(char*) field->field_name,
col_type,
dtype_form_prtype(
......
......@@ -462,7 +462,8 @@ ibuf_data_init_for_space(
page_t* root;
page_t* header_page;
mtr_t mtr;
char buf[50];
char* buf;
mem_heap_t* heap;
dict_table_t* table;
dict_index_t* index;
ulint n_used;
......@@ -516,16 +517,20 @@ ibuf_data_init_for_space(
ibuf_exit();
heap = mem_heap_create(450);
buf = mem_heap_alloc(heap, 50);
sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space);
/* use old-style record format for the insert buffer */
table = dict_mem_table_create(buf, space, 2, 0);
dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "TYPES", DATA_BINARY, 0, 0);
table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
mem_heap_free(heap);
index = dict_mem_index_create(
buf, "CLUST_IND", space,
......@@ -1139,7 +1144,7 @@ ibuf_dummy_index_add_col(
ulint len) /* in: length of the column */
{
ulint i = index->table->n_def;
dict_mem_table_add_col(index->table, "DUMMY",
dict_mem_table_add_col(index->table, NULL, NULL,
dtype_get_mtype(type),
dtype_get_prtype(type),
dtype_get_len(type));
......
......@@ -213,12 +213,21 @@ dict_table_autoinc_unlock(
/*======================*/
dict_table_t* table); /* in: table */
/**************************************************************************
Adds system columns to a table object. */
void
dict_table_add_system_columns(
/*==========================*/
dict_table_t* table, /* in/out: table */
mem_heap_t* heap); /* in: temporary heap */
/**************************************************************************
Adds a table object to the dictionary cache. */
void
dict_table_add_to_cache(
/*====================*/
dict_table_t* table); /* in: table */
dict_table_t* table, /* in: table */
mem_heap_t* heap); /* in: temporary heap */
/**************************************************************************
Removes a table object from the dictionary cache. */
......
......@@ -72,7 +72,8 @@ void
dict_mem_table_add_col(
/*===================*/
dict_table_t* table, /* in: table */
const char* name, /* in: column name */
mem_heap_t* heap, /* in: temporary memory heap, or NULL */
const char* name, /* in: column name, or NULL */
ulint mtype, /* in: main datatype */
ulint prtype, /* in: precise type */
ulint len); /* in: precision */
......
......@@ -517,8 +517,9 @@ mlog_parse_index(
n = mach_read_from_2(ptr);
ptr += 2;
n_uniq = mach_read_from_2(ptr);
ptr += 2;
ut_ad(n_uniq <= n);
if (end_ptr < ptr + (n + 1) * 2) {
if (end_ptr < ptr + n * 2) {
return(NULL);
}
} else {
......@@ -531,18 +532,18 @@ mlog_parse_index(
ind->table = table;
ind->n_uniq = (unsigned int) n_uniq;
if (n_uniq != n) {
ut_a(n_uniq + DATA_ROLL_PTR <= n);
ind->type = DICT_CLUSTERED;
}
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
ind->cached = TRUE;
if (comp) {
for (i = 0; i < n; i++) {
ulint len = mach_read_from_2(ptr += 2);
ulint len = mach_read_from_2(ptr);
ptr += 2;
/* The high-order bit of len is the NOT NULL flag;
the rest is 0 or 0x7fff for variable-length fields,
and 1..0x7ffe for fixed-length fields. */
dict_mem_table_add_col(
table, "DUMMY",
table, NULL, NULL,
((len + 1) & 0x7fff) <= 1
? DATA_BINARY : DATA_FIXBINARY,
len & 0x8000 ? DATA_NOT_NULL : 0,
......@@ -552,8 +553,23 @@ mlog_parse_index(
dict_table_get_nth_col(table, i),
0);
}
ptr += 2;
dict_table_add_system_columns(table, table->heap);
if (n_uniq != n) {
/* Identify DB_TRX_ID and DB_ROLL_PTR in the index. */
ut_a(DATA_TRX_ID_LEN
== dict_index_get_nth_col(ind, DATA_TRX_ID - 1
+ n_uniq)->len);
ut_a(DATA_ROLL_PTR_LEN
== dict_index_get_nth_col(ind, DATA_ROLL_PTR - 1
+ n_uniq)->len);
ind->fields[DATA_TRX_ID - 1 + n_uniq].col
= &table->cols[n + DATA_TRX_ID];
ind->fields[DATA_ROLL_PTR - 1 + n_uniq].col
= &table->cols[n + DATA_ROLL_PTR];
}
}
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
ind->cached = TRUE;
*index = ind;
return(ptr);
}
......@@ -1640,7 +1640,8 @@ pars_create_table(
while (column) {
dtype = dfield_get_type(que_node_get_val(column));
dict_mem_table_add_col(table, column->name, dtype->mtype,
dict_mem_table_add_col(table, table->heap,
column->name, dtype->mtype,
dtype->prtype, dtype->len);
column->resolved = TRUE;
column->token_type = SYM_COLUMN;
......
......@@ -907,7 +907,7 @@ srv_init(void)
/* create dummy table and index for old-style infimum and supremum */
table = dict_mem_table_create("SYS_DUMMY1",
DICT_HDR_SPACE, 1, 0);
dict_mem_table_add_col(table, "DUMMY", DATA_CHAR,
dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
DATA_ENGLISH | DATA_NOT_NULL, 8);
srv_sys->dummy_ind1 = dict_mem_index_create(
......@@ -918,7 +918,7 @@ srv_init(void)
/* create dummy table and index for new-style infimum and supremum */
table = dict_mem_table_create("SYS_DUMMY2",
DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
dict_mem_table_add_col(table, "DUMMY", DATA_CHAR,
dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
DATA_ENGLISH | DATA_NOT_NULL, 8);
srv_sys->dummy_ind2 = dict_mem_index_create(
"SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
......
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