From 672290b03d6f3c0ffb3e89ed6e38148b0eca84f5 Mon Sep 17 00:00:00 2001 From: "istruewing@stella.local" <> Date: Thu, 18 Oct 2007 16:14:27 +0200 Subject: [PATCH] Bug#31692 - binlog_killed.test crashes sometimes The server crashed when a thread was killed while locking the general_log table at statement begin. The general_log table is handled like a performance schema table. The state of open tables is saved and cleared so that this table seems to be the only open one. Then this table is opened and locked. After writing, the table is closed and the open table state is restored. Before restoring, however, it is asserted that there is no current table open. After locking the table, mysql_lock_tables() checks if the thread was killed in between. If so, it unlocks the table and returns an error. open_ltable() just returns with the error and leaves closing of the table to close_thread_tables(), which is called at statement end. open_performance_schema_table() did not take this into account. It assumed that a failed open_ltable() would not leave an open table behind. Fixed by closing thread tables after open_ltable() and before restore_backup_open_tables_state() if the thread was killed. No test case. It requires correctly timed parallel execution. Since this bug was detected by the test suite, it seems dispensable to add another test. --- sql/sql_base.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 337fde53dac..c487c5f034e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7748,7 +7748,17 @@ open_performance_schema_table(THD *thd, TABLE_LIST *one_table, table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; } else + { + /* + If error in mysql_lock_tables(), open_ltable doesn't close the + table. Thread kill during mysql_lock_tables() is such error. But + open tables cannot be accepted when restoring the open tables + state. + */ + if (thd->killed) + close_thread_tables(thd); thd->restore_backup_open_tables_state(backup); + } thd->utime_after_lock= save_utime_after_lock; DBUG_RETURN(table);