Commit 7953594a authored by ingo@mysql.com's avatar ingo@mysql.com

Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement

Solution for 5.0.
Changed calls to open_table(). Requested to ignore
flush at places where the command did already lock tables.
This could happen in CREATE ... SELECT and ALTER TABLE.

No test case. The bug can only be triggered by true concurrency.
The stress test suite provides a test case for this.
parent ffc213a1
......@@ -1030,23 +1030,23 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
SYNOPSIS
open_table()
thd Thread context
table_list Open first table in list
refresh Pointer to memory that will be set to 1 if
we need to close all tables and reopen them
If this is a NULL pointer, then the is no version
number checking and the table is not put in the
thread-open-list
flags Bitmap of flags to modify how open works:
MYSQL_LOCK_IGNORE_FLUSH - Open table even if someone
has done a flush or namelock on it.
thd Thread context.
table_list Open first table in list.
refresh INOUT Pointer to memory that will be set to 1 if
we need to close all tables and reopen them.
If this is a NULL pointer, then the table is not
put in the thread-open-list.
flags Bitmap of flags to modify how open works:
MYSQL_LOCK_IGNORE_FLUSH - Open table even if
someone has done a flush or namelock on it.
No version number checking is done.
IMPLEMENTATION
Uses a cache of open tables to find a table not in use.
RETURN
NULL Open failed. If refresh is set then one should close
all other tables and retry the open
all other tables and retry the open.
# Success. Pointer to TABLE object for open table.
*/
......@@ -1201,10 +1201,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if (!thd->open_tables)
thd->version=refresh_version;
else if (thd->version != refresh_version && refresh)
else if ((thd->version != refresh_version) &&
! (flags & MYSQL_LOCK_IGNORE_FLUSH))
{
/* Someone did a refresh while thread was opening tables */
*refresh=1;
if (refresh)
*refresh=1;
VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(0);
}
......
......@@ -1756,7 +1756,8 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
create_info, *extra_fields, *keys, 0,
select_field_count))
{
if (!(table= open_table(thd, create_table, thd->mem_root, (bool*)0, 0)))
if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
MYSQL_LOCK_IGNORE_FLUSH)))
quick_rm_table(create_info->db_type, create_table->db,
table_case_name(create_info, create_table->table_name));
}
......@@ -3579,7 +3580,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
bzero((void*) &tbl, sizeof(tbl));
tbl.db= new_db;
tbl.table_name= tbl.alias= tmp_name;
new_table= open_table(thd, &tbl, thd->mem_root, 0, 0);
new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
MYSQL_LOCK_IGNORE_FLUSH);
}
else
{
......
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