mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
Fix bug #18934, "InnoDB crashes when table uses column names like
DB_ROW_ID", by refusing tables that use reserved column names. Add dict_mem_table_free(), use it instead of duplicating the code everywhere. Use already existing dict_mem_index_free(). Fix memory leaks in row_create_table_for_mysql() in rare corner cases.
This commit is contained in:
parent
6384ac2043
commit
b6e02dd207
9 changed files with 98 additions and 10 deletions
|
@ -1257,15 +1257,13 @@ dict_table_remove_from_cache(
|
||||||
/* Remove table from LRU list of tables */
|
/* Remove table from LRU list of tables */
|
||||||
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
|
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
|
||||||
|
|
||||||
mutex_free(&(table->autoinc_mutex));
|
|
||||||
|
|
||||||
size = mem_heap_get_size(table->heap);
|
size = mem_heap_get_size(table->heap);
|
||||||
|
|
||||||
ut_ad(dict_sys->size >= size);
|
ut_ad(dict_sys->size >= size);
|
||||||
|
|
||||||
dict_sys->size -= size;
|
dict_sys->size -= size;
|
||||||
|
|
||||||
mem_heap_free(table->heap);
|
dict_mem_table_free(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -1386,6 +1384,38 @@ dict_col_reposition_in_cache(
|
||||||
HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
|
HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
If the given column name is reserved for InnoDB system columns, return
|
||||||
|
TRUE. */
|
||||||
|
|
||||||
|
ibool
|
||||||
|
dict_col_name_is_reserved(
|
||||||
|
/*======================*/
|
||||||
|
/* out: TRUE if name is reserved */
|
||||||
|
const char* name) /* in: column name */
|
||||||
|
{
|
||||||
|
/* This check reminds that if a new system column is added to
|
||||||
|
the program, it should be dealt with here. */
|
||||||
|
#if DATA_N_SYS_COLS != 4
|
||||||
|
#error "DATA_N_SYS_COLS != 4"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char* reserved_names[] = {
|
||||||
|
"DB_ROW_ID", "DB_TRX_ID", "DB_ROLL_PTR", "DB_MIX_ID"
|
||||||
|
};
|
||||||
|
|
||||||
|
ulint i;
|
||||||
|
|
||||||
|
for (i = 0; i < UT_ARR_SIZE(reserved_names); i++) {
|
||||||
|
if (strcmp(name, reserved_names[i]) == 0) {
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Adds an index to the dictionary cache. */
|
Adds an index to the dictionary cache. */
|
||||||
|
|
||||||
|
@ -1548,7 +1578,7 @@ dict_index_remove_from_cache(
|
||||||
|
|
||||||
dict_sys->size -= size;
|
dict_sys->size -= size;
|
||||||
|
|
||||||
mem_heap_free(index->heap);
|
dict_mem_index_free(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -94,6 +94,21 @@ dict_mem_table_create(
|
||||||
return(table);
|
return(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
Free a table memory object. */
|
||||||
|
|
||||||
|
void
|
||||||
|
dict_mem_table_free(
|
||||||
|
/*================*/
|
||||||
|
dict_table_t* table) /* in: table */
|
||||||
|
{
|
||||||
|
ut_ad(table);
|
||||||
|
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||||
|
|
||||||
|
mutex_free(&(table->autoinc_mutex));
|
||||||
|
mem_heap_free(table->heap);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Adds a column definition to a table. */
|
Adds a column definition to a table. */
|
||||||
|
|
||||||
|
@ -245,5 +260,8 @@ dict_mem_index_free(
|
||||||
/*================*/
|
/*================*/
|
||||||
dict_index_t* index) /* in: index */
|
dict_index_t* index) /* in: index */
|
||||||
{
|
{
|
||||||
|
ut_ad(index);
|
||||||
|
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
||||||
|
|
||||||
mem_heap_free(index->heap);
|
mem_heap_free(index->heap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1170,9 +1170,9 @@ ibuf_dummy_index_free(
|
||||||
dict_index_t* index) /* in: dummy index */
|
dict_index_t* index) /* in: dummy index */
|
||||||
{
|
{
|
||||||
dict_table_t* table = index->table;
|
dict_table_t* table = index->table;
|
||||||
mem_heap_free(index->heap);
|
|
||||||
mutex_free(&(table->autoinc_mutex));
|
dict_mem_index_free(index);
|
||||||
mem_heap_free(table->heap);
|
dict_mem_table_free(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
|
@ -100,6 +100,15 @@ ulint
|
||||||
dict_col_get_clust_pos(
|
dict_col_get_clust_pos(
|
||||||
/*===================*/
|
/*===================*/
|
||||||
dict_col_t* col);
|
dict_col_t* col);
|
||||||
|
/********************************************************************
|
||||||
|
If the given column name is reserved for InnoDB system columns, return
|
||||||
|
TRUE. */
|
||||||
|
|
||||||
|
ibool
|
||||||
|
dict_col_name_is_reserved(
|
||||||
|
/*======================*/
|
||||||
|
/* out: TRUE if name is reserved */
|
||||||
|
const char* name); /* in: column name */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Initializes the autoinc counter. It is not an error to initialize an already
|
Initializes the autoinc counter. It is not an error to initialize an already
|
||||||
initialized counter. */
|
initialized counter. */
|
||||||
|
|
|
@ -58,6 +58,13 @@ dict_mem_table_create(
|
||||||
a member of a cluster */
|
a member of a cluster */
|
||||||
ulint n_cols, /* in: number of columns */
|
ulint n_cols, /* in: number of columns */
|
||||||
ulint flags); /* in: table flags */
|
ulint flags); /* in: table flags */
|
||||||
|
/********************************************************************
|
||||||
|
Free a table memory object. */
|
||||||
|
|
||||||
|
void
|
||||||
|
dict_mem_table_free(
|
||||||
|
/*================*/
|
||||||
|
dict_table_t* table); /* in: table */
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Adds a column definition to a table. */
|
Adds a column definition to a table. */
|
||||||
|
|
||||||
|
|
|
@ -897,9 +897,9 @@ recv_parse_or_apply_log_rec_body(
|
||||||
ut_ad(!page || ptr);
|
ut_ad(!page || ptr);
|
||||||
if (index) {
|
if (index) {
|
||||||
dict_table_t* table = index->table;
|
dict_table_t* table = index->table;
|
||||||
mem_heap_free(index->heap);
|
|
||||||
mutex_free(&(table->autoinc_mutex));
|
dict_mem_index_free(index);
|
||||||
mem_heap_free(table->heap);
|
dict_mem_table_free(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ptr);
|
return(ptr);
|
||||||
|
|
|
@ -3333,3 +3333,5 @@ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
commit;
|
commit;
|
||||||
drop table t1, t2, t3, t5, t6, t8, t9;
|
drop table t1, t2, t3, t5, t6, t8, t9;
|
||||||
|
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
|
||||||
|
ERROR HY000: Can't create table 'test.t1' (errno: -1)
|
||||||
|
|
|
@ -2355,3 +2355,7 @@ disconnect h;
|
||||||
disconnect i;
|
disconnect i;
|
||||||
disconnect j;
|
disconnect j;
|
||||||
drop table t1, t2, t3, t5, t6, t8, t9;
|
drop table t1, t2, t3, t5, t6, t8, t9;
|
||||||
|
|
||||||
|
# bug 18934, "InnoDB crashes when table uses column names like DB_ROW_ID"
|
||||||
|
--error 1005
|
||||||
|
CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
|
||||||
|
|
|
@ -1675,7 +1675,9 @@ row_mysql_recover_tmp_table(
|
||||||
|
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
/* table name does not begin with "/rsql" */
|
/* table name does not begin with "/rsql" */
|
||||||
|
dict_mem_table_free(table);
|
||||||
trx_commit_for_mysql(trx);
|
trx_commit_for_mysql(trx);
|
||||||
|
|
||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1787,6 +1789,7 @@ row_create_table_for_mysql(
|
||||||
const char* table_name;
|
const char* table_name;
|
||||||
ulint table_name_len;
|
ulint table_name_len;
|
||||||
ulint err;
|
ulint err;
|
||||||
|
ulint i;
|
||||||
|
|
||||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
|
@ -1804,6 +1807,7 @@ row_create_table_for_mysql(
|
||||||
"InnoDB: with raw, and innodb_force_... is removed.\n",
|
"InnoDB: with raw, and innodb_force_... is removed.\n",
|
||||||
stderr);
|
stderr);
|
||||||
|
|
||||||
|
dict_mem_table_free(table);
|
||||||
trx_commit_for_mysql(trx);
|
trx_commit_for_mysql(trx);
|
||||||
|
|
||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
|
@ -1818,11 +1822,25 @@ row_create_table_for_mysql(
|
||||||
"InnoDB: MySQL system tables must be of the MyISAM type!\n",
|
"InnoDB: MySQL system tables must be of the MyISAM type!\n",
|
||||||
table->name);
|
table->name);
|
||||||
|
|
||||||
|
dict_mem_table_free(table);
|
||||||
trx_commit_for_mysql(trx);
|
trx_commit_for_mysql(trx);
|
||||||
|
|
||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that no reserved column names are used. */
|
||||||
|
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
|
||||||
|
dict_col_t* col = dict_table_get_nth_col(table, i);
|
||||||
|
|
||||||
|
if (dict_col_name_is_reserved(col->name)) {
|
||||||
|
|
||||||
|
dict_mem_table_free(table);
|
||||||
|
trx_commit_for_mysql(trx);
|
||||||
|
|
||||||
|
return(DB_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trx_start_if_not_started(trx);
|
trx_start_if_not_started(trx);
|
||||||
|
|
||||||
if (row_mysql_is_recovered_tmp_table(table->name)) {
|
if (row_mysql_is_recovered_tmp_table(table->name)) {
|
||||||
|
|
Loading…
Reference in a new issue