From: Dmitry Shulga Date: May 31 2011 1:43pm Subject: bzr commit into mysql-5.1 branch (Dmitry.Shulga:3634) Bug#47870 Bug#11756013 List-Archive: http://lists.mysql.com/commits/138454 X-Bug: 47870,11756013 Message-Id: <201105311343.p4VDhgf6018420@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2822259496229619725==" --===============2822259496229619725== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/shulga/projects/mysql/mysql-5.1-bug11756013/ based on revid:davi.arnaut@stripped 3634 Dmitry Shulga 2011-05-31 Fixed Bug#11756013 (formerly known as bug#47870): BOGUS "THE TABLE MYSQL.PROC IS MISSING,..." There is a race condition during concurrent processing of CALL statement to some procedure specified by full qualified name SCHEMA_NAME.PROC_NAME and processing of DROP SCHEMA_NAME. The problem was that there is a window for race condition when one server thread try to load a stored procedure/function being executed and other thread try to drop schema that is part of fully qualified name of procedure/function being executed. This condition race window exists in implementation of function mysql_change_db() called by db_load_routine() during loading of stored procedure/function to cache. Function mysql_change_db() calls to check_db_dir_existence() that might failed because specified database was dropped during concurrent execution of DROP SCHEMA statememt. 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 procedure/function 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 solution is to install error hadler inside db_load_routine() before call to mysql_opt_change_db() and deinstall after this functuon executed. If error handler called as a result of db check failure it remembered this event and later inside db_load_routine() we can check value of this event. If this event is signaled about droped schema then we call to my_error to set error in diagnostic area to error ER_BAD_DB_ERROR. @ sql/sql_db.cc Added synchronization point "before_db_dir_check" to emulate a race condition during processing of CALL/DROP SCHEMA. modified: mysql-test/t/sp_sync.test sql/sp.cc sql/sql_db.cc === modified file 'mysql-test/t/sp_sync.test' --- a/mysql-test/t/sp_sync.test 2010-01-15 08:51:39 +0000 +++ b/mysql-test/t/sp_sync.test 2011-05-31 13:43:02 +0000 @@ -54,5 +54,25 @@ connection default; DROP TABLE t1, t2; DROP PROCEDURE p1; +--echo # +--echo # test for bug# +--echo # + +CREATE SCHEMA s1; +CREATE PROCEDURE s1.p1() BEGIN END; + +connect (con2, localhost, root); +SET DEBUG_SYNC='before_db_dir_check SIGNAL check_db WAIT_FOR dropped_schema'; +--send CALL s1.p1 + +connection default; +SET DEBUG_SYNC='now WAIT_FOR check_db'; +DROP SCHEMA s1; +SET DEBUG_SYNC='now SIGNAL dropped_schema'; + +connection con2; +--error ER_BAD_DB_ERROR +--reap + SET DEBUG_SYNC = 'RESET'; === modified file 'sql/sp.cc' --- a/sql/sp.cc 2010-06-11 12:52:06 +0000 +++ b/sql/sp.cc 2011-05-31 13:43:02 +0000 @@ -707,6 +707,35 @@ Silence_deprecated_warning::handle_error return FALSE; } +struct Catch_db_not_exists_error : public Internal_error_handler +{ +public: + Catch_db_not_exists_error(bool* db_not_exist) + : schema_not_exist(db_not_exist) + {} + virtual bool handle_error(uint sql_errno, const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd); +private: + bool* schema_not_exist; +}; + +bool +Catch_db_not_exists_error::handle_error(uint sql_errno, const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd) +{ + *schema_not_exist= false; + + if (sql_errno == ER_BAD_DB_ERROR && + level == MYSQL_ERROR::WARN_LEVEL_NOTE) + { + *schema_not_exist= true; + return true; + } + return false; +} + static int db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, @@ -720,12 +749,12 @@ db_load_routine(THD *thd, int type, sp_n char saved_cur_db_name_buf[NAME_LEN+1]; LEX_STRING saved_cur_db_name= { saved_cur_db_name_buf, sizeof(saved_cur_db_name_buf) }; - bool cur_db_changed; + bool cur_db_changed, db_not_exists; ulong old_sql_mode= thd->variables.sql_mode; ha_rows old_select_limit= thd->variables.select_limit; sp_rcontext *old_spcont= thd->spcont; Silence_deprecated_warning warning_handler; - + Catch_db_not_exists_error db_not_exists_handler(&db_not_exists); char definer_user_name_holder[USERNAME_LENGTH + 1]; LEX_STRING definer_user_name= { definer_user_name_holder, USERNAME_LENGTH }; @@ -766,6 +795,7 @@ db_load_routine(THD *thd, int type, sp_n goto end; } + thd->push_internal_handler(&db_not_exists_handler); /* Change the current database (if needed). @@ -776,9 +806,17 @@ db_load_routine(THD *thd, int type, sp_n &cur_db_changed)) { ret= SP_INTERNAL_ERROR; + thd->pop_internal_handler(); goto end; } + thd->pop_internal_handler(); + if (db_not_exists) + { + ret= SP_INTERNAL_ERROR; + my_error(ER_BAD_DB_ERROR, MYF(0), name->m_db.str); + goto end; + } thd->spcont= NULL; { === modified file 'sql/sql_db.cc' --- a/sql/sql_db.cc 2010-12-10 07:48:50 +0000 +++ b/sql/sql_db.cc 2011-05-31 13:43:02 +0000 @@ -26,6 +26,7 @@ #ifdef __WIN__ #include #endif +#include "debug_sync.h" #define MAX_DROP_TABLE_Q_LEN 1024 @@ -1702,6 +1703,8 @@ bool mysql_change_db(THD *thd, const LEX } #endif + DEBUG_SYNC(thd, "before_db_dir_check"); + if (check_db_dir_existence(new_db_file_name.str)) { if (force_switch) --===============2822259496229619725== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dmitry.shulga@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dmitry.shulga@stripped\ # ct94ykjvm02d6m4p # target_branch: file:///Users/shulga/projects/mysql/mysql-5.1-\ # bug11756013/ # testament_sha1: 43967515c1eab975e5f89bd5a8d86f344bcfb418 # timestamp: 2011-05-31 20:43:36 +0700 # base_revision_id: davi.arnaut@stripped\ # gek17uxbyt23m0ct # # Begin bundle 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 g2DMx5u/4u5IpwoSApCIC8A= --===============2822259496229619725==--