summaryrefslogtreecommitdiff
path: root/sql/sql_insert.cc
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2005-05-31 11:08:14 +0200
committerunknown <ingo@mysql.com>2005-05-31 11:08:14 +0200
commitcf2188ca398e12d4a10c50b069c2243825f9dced (patch)
treea57814a50ac22d55c9f811df170159eea1b1eb3c /sql/sql_insert.cc
parente1e1e3a8498160d988e7ea5be7ef0646021e5817 (diff)
downloadmariadb-git-cf2188ca398e12d4a10c50b069c2243825f9dced.tar.gz
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().
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r--sql/sql_insert.cc24
1 files changed, 18 insertions, 6 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index c6b7b1d6c15..b61c766120e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -674,10 +674,13 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
Avoid that a global read lock steps in while we are creating the
new thread. It would block trying to open the table. Hence, the
DI thread and this thread would wait until after the global
- readlock is gone. If the read lock exists already, we leave with
- no table and then switch to non-delayed insert.
+ readlock is gone. Since the insert thread needs to wait for a
+ global read lock anyway, we do it right now. 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().
*/
- if (set_protect_against_global_read_lock())
+ if (wait_if_global_read_lock(thd, 0, 1))
goto err;
if (!(tmp=new delayed_insert()))
{
@@ -719,7 +722,11 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
pthread_cond_wait(&tmp->cond_client,&tmp->mutex);
}
pthread_mutex_unlock(&tmp->mutex);
- unset_protect_against_global_read_lock();
+ /*
+ 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);
thd->proc_info="got old table";
if (tmp->thd.killed)
{
@@ -755,7 +762,11 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
err1:
thd->fatal_error= 1;
- unset_protect_against_global_read_lock();
+ /*
+ 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);
err:
pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(0); // Continue with normal insert
@@ -1105,7 +1116,8 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
handler will close the table and finish when the outstanding
inserts are done.
*/
- if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, TRUE)))
+ if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1,
+ MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)))
{
di->dead=thd->killed=1; // Fatal error
}