summaryrefslogtreecommitdiff
path: root/sql/sql_db.cc
diff options
context:
space:
mode:
authorDmitry Shulga <Dmitry.Shulga@oracle.com>2011-06-23 20:41:04 +0700
committerDmitry Shulga <Dmitry.Shulga@oracle.com>2011-06-23 20:41:04 +0700
commit07056eb984573b483576d45d7b8c259ad66dcd66 (patch)
treeade6ce3b5681ea2fa357915b4210ff12d7af9d9c /sql/sql_db.cc
parentb3696af2e66fb4d72815d2d7754740c2fd8043fd (diff)
downloadmariadb-git-07056eb984573b483576d45d7b8c259ad66dcd66.tar.gz
Fixed Bug#11756013 (formerly known as bug#47870):
BOGUS "THE TABLE MYSQL.PROC IS MISSING,..." There was a race condition between loading a stored routine (function/procedure/trigger) specified by fully qualified name SCHEMA_NAME.PROC_NAME and dropping the stored routine database. The problem was that there is a window for race condition when one server thread tries to load a stored routine being executed and the other thread tries to drop the stored routine schema. This condition race window exists in implementation of function mysql_change_db() called by db_load_routine() during loading of stored routine to cache. Function mysql_change_db() calls check_db_dir_existence() that might failed because specified database was dropped during concurrent execution of DROP SCHEMA statement. db_load_routine() calls mysql_change_db() with flag 'force_switch' set to 'true' value so when referenced db is not found then my_error() is not called and function mysql_change_db() returns ok. This shadows information about schema opening error in db_load_routine(). Then db_load_routine() makes attempt to parse stored routine that is failed. This makes to return error to sp_cache_routines_and_add_tables_aux() but since during error generation a call to my_error wasn't made and hence THD::main_da wasn't set we set the generic "mysql.proc table corrupt" error when running sp_cache_routines_and_add_tables_aux(). The fix is to install an error handler inside db_load_routine() for the mysql_op_change_db() call, and check later if the ER_BAD_DB_ERROR was caught.
Diffstat (limited to 'sql/sql_db.cc')
-rw-r--r--sql/sql_db.cc3
1 files changed, 3 insertions, 0 deletions
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index d7d7f43a7aa..e0d848321a7 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -26,6 +26,7 @@
#ifdef __WIN__
#include <direct.h>
#endif
+#include "debug_sync.h"
#define MAX_DROP_TABLE_Q_LEN 1024
@@ -1702,6 +1703,8 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
}
#endif
+ DEBUG_SYNC(thd, "before_db_dir_check");
+
if (check_db_dir_existence(new_db_file_name.str))
{
if (force_switch)