mirror of
https://github.com/MariaDB/server.git
synced 2026-04-24 01:05:30 +02:00
Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement.
1.) Added a new option to mysql_lock_tables() for ignoring FLUSH TABLES. Used the new option in create_table_from_items(). It is necessary to prevent the SELECT table from being reopend. It would get new storage assigned for its fields, while the SELECT part of the command would still use the old (freed) storage. 2.) Protected the CREATE TABLE and CREATE TABLE ... SELECT commands against a global read lock. This prevents a deadlock in CREATE TABLE ... SELECT in conjunction with FLUSH TABLES WITH READ LOCK and avoids the creation of new tables during a global read lock. 3.) Replaced set_protect_against_global_read_lock() and unset_protect_against_global_read_lock() by wait_if_global_read_lock() and start_waiting_global_read_lock() in the INSERT DELAYED handling. mysql-test/r/create.result: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Added test results. mysql-test/t/create.test: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Added tests which do not require concurrency. sql/lock.cc: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Added a new option to mysql_lock_tables() for ignoring FLUSH TABLES. Changed the parameter list. Removed two unnecessary functions. Their functionality is included in wait_if_global_read_lock() and start_waiting_global_read_lock(). sql/mysql_priv.h: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Changed the declaration of mysql_lock_tables(). Added definitions for the new options. sql/sql_acl.cc: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Adjusted mysql_lock_tables() calls to the new argument list. sql/sql_base.cc: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Adjusted mysql_lock_tables() calls to the new argument list. sql/sql_handler.cc: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Adjusted mysql_lock_tables() calls to the new argument list. sql/sql_insert.cc: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Replaced set_protect_against_global_read_lock() and unset_protect_against_global_read_lock() by wait_if_global_read_lock() and start_waiting_global_read_lock() in the INSERT DELAYED handling. Adjusted mysql_lock_tables() calls to the new argument list. sql/sql_parse.cc: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Protected the CREATE TABLE and CREATE TABLE ... SELECT commands against a global read lock. This prevents a deadlock in CREATE TABLE ... SELECT in conjunction with FLUSH TABLES WITH READ LOCK and avoids the creation of new tables during a global read lock. sql/sql_table.cc: Bug#10224 - ANALYZE TABLE crashing with simultaneous CREATE ... SELECT statement. Adjusted mysql_lock_tables() calls to the new argument list. Used the new option in create_table_from_items().
This commit is contained in:
parent
e1e1e3a849
commit
cf2188ca39
10 changed files with 108 additions and 66 deletions
|
|
@ -1673,6 +1673,24 @@ mysql_execute_command(void)
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
The create-select command will open and read-lock the select table
|
||||
and then create, open and write-lock the new table. If a global
|
||||
read lock steps in, we get a deadlock. The write lock waits for
|
||||
the global read lock, while the global read lock waits for the
|
||||
select table to be closed. So we wait until the global readlock is
|
||||
gone before starting both steps. Note that
|
||||
wait_if_global_read_lock() sets a protection against a new global
|
||||
read lock when it succeeds. This needs to be released by
|
||||
start_waiting_global_read_lock(). We protect the normal CREATE
|
||||
TABLE in the same way. That way we avoid that a new table is
|
||||
created during a gobal read lock.
|
||||
*/
|
||||
if (wait_if_global_read_lock(thd, 0, 1))
|
||||
{
|
||||
res= -1;
|
||||
break;
|
||||
}
|
||||
if (select_lex->item_list.elements) // With select
|
||||
{
|
||||
select_result *result;
|
||||
|
|
@ -1681,7 +1699,7 @@ mysql_execute_command(void)
|
|||
check_dup(tables->db, tables->real_name, tables->next))
|
||||
{
|
||||
net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
|
||||
DBUG_VOID_RETURN;
|
||||
goto error1;
|
||||
}
|
||||
if (lex->create_info.used_fields & HA_CREATE_USED_UNION)
|
||||
{
|
||||
|
|
@ -1692,7 +1710,7 @@ mysql_execute_command(void)
|
|||
(TABLE_LIST*)lex->create_info.merge_list.first))
|
||||
{
|
||||
net_printf(&thd->net, ER_INSERT_TABLE_USED, tab->real_name);
|
||||
DBUG_VOID_RETURN;
|
||||
goto error1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1700,7 +1718,7 @@ mysql_execute_command(void)
|
|||
{
|
||||
TABLE_LIST *table;
|
||||
if (check_table_access(thd, SELECT_ACL, tables->next))
|
||||
goto error; // Error message is given
|
||||
goto error1; // Error message is given
|
||||
/* TODO: Delete the following loop when locks is set by sql_yacc */
|
||||
for (table = tables->next ; table ; table=table->next)
|
||||
table->lock_type= lex->lock_option;
|
||||
|
|
@ -1737,6 +1755,11 @@ mysql_execute_command(void)
|
|||
if (!res)
|
||||
send_ok(&thd->net);
|
||||
}
|
||||
/*
|
||||
Release the protection against the global read lock and wake
|
||||
everyone, who might want to set a global read lock.
|
||||
*/
|
||||
start_waiting_global_read_lock(thd);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_CREATE_INDEX:
|
||||
|
|
@ -2674,6 +2697,14 @@ error:
|
|||
thd->lock= 0;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
error1:
|
||||
/*
|
||||
Release the protection against the global read lock and wake
|
||||
everyone, who might want to set a global read lock.
|
||||
*/
|
||||
start_waiting_global_read_lock(thd);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue