From: Jon Olav Hauglid Date: March 3 2011 3:45pm Subject: bzr commit into mysql-5.5 branch (jon.hauglid:3368) Bug#57649 List-Archive: http://lists.mysql.com/commits/132388 X-Bug: 57649 Message-Id: <201103031547.p23EqUpa004027@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1850890957085875694==" --===============1850890957085875694== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/x/mysql-5.5-bug57649/ based on revid:alexander.barkov@stripped 3368 Jon Olav Hauglid 2011-03-03 Bug #57649 FLUSH TABLES under FLUSH TABLES WITH READ LOCK leads to assert failure. This assert was triggered if a statement tried up upgrade a metadata lock with an active FLUSH TABLE WITH READ LOCK. The assert checks that the connection already holds a global intention exclusive metadata lock. However, FLUSH TABLE WITH READ LOCK does not acquire this lock in order to be compatible with FLUSH TABLES WITH READ LOCK. Therefore any metadata lock upgrade caused the assert to be triggered. This patch fixes the problem by preventing metadata lock upgrade if the connection has an active FLUSH TABLE WITH READ LOCK. ER_TABLE_NOT_LOCKED_FOR_WRITE will instead be reported to the client. Test case added to flush.test. modified: mysql-test/r/flush.result mysql-test/t/flush.test sql/sql_base.cc sql/sql_base.h sql/sql_reload.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_truncate.cc === modified file 'mysql-test/r/flush.result' --- a/mysql-test/r/flush.result 2010-11-11 17:11:05 +0000 +++ b/mysql-test/r/flush.result 2011-03-03 15:45:28 +0000 @@ -451,3 +451,18 @@ unlock tables; handler t1 close; # Cleanup. drop tables t1, t2; +# +# Bug#57649 FLUSH TABLES under FLUSH TABLES WITH READ LOCK leads +# to assert failure. +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT); +FLUSH TABLES t1 WITH READ LOCK; +FLUSH TABLES; +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a= 1; +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +ALTER TABLE t1 COMMENT 'test'; +ERROR HY000: Table 't1' was locked with a READ lock and can't be updated +UNLOCK TABLES; +DROP TABLE t1; === modified file 'mysql-test/t/flush.test' --- a/mysql-test/t/flush.test 2010-11-11 17:11:05 +0000 +++ b/mysql-test/t/flush.test 2011-03-03 15:45:28 +0000 @@ -644,3 +644,27 @@ disconnect con2; --source include/wait_until_disconnected.inc connection default; drop tables t1, t2; + + +--echo # +--echo # Bug#57649 FLUSH TABLES under FLUSH TABLES WITH READ LOCK leads +--echo # to assert failure. +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT); +FLUSH TABLES t1 WITH READ LOCK; + +# All these triggered the assertion +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +FLUSH TABLES; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a= 1; +--error ER_TABLE_NOT_LOCKED_FOR_WRITE +ALTER TABLE t1 COMMENT 'test'; + +UNLOCK TABLES; +DROP TABLE t1; === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2011-02-08 15:47:33 +0000 +++ b/sql/sql_base.cc 2011-03-03 15:45:28 +0000 @@ -1026,7 +1026,7 @@ bool close_cached_tables(THD *thd, TABLE table_list= table_list->next_global) { /* A check that the table was locked for write is done by the caller. */ - TABLE *table= find_table_for_mdl_upgrade(thd->open_tables, table_list->db, + TABLE *table= find_table_for_mdl_upgrade(thd, table_list->db, table_list->table_name, TRUE); /* May return NULL if this table has already been closed via an alias. */ @@ -3120,7 +3120,7 @@ TABLE *find_locked_table(TABLE *list, co lock from the list of open tables, emit error if no such table found. - @param list List of TABLE objects to be searched + @param thd Thread context @param db Database name. @param table_name Name of table. @param no_error Don't emit error if no suitable TABLE @@ -3131,11 +3131,10 @@ TABLE *find_locked_table(TABLE *list, co lock, NULL otherwise. */ -TABLE *find_table_for_mdl_upgrade(TABLE *list, const char *db, - const char *table_name, - bool no_error) +TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, + const char *table_name, bool no_error) { - TABLE *tab= find_locked_table(list, db, table_name); + TABLE *tab= find_locked_table(thd->open_tables, db, table_name); if (!tab) { @@ -3143,19 +3142,28 @@ TABLE *find_table_for_mdl_upgrade(TABLE my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_name); return NULL; } - else + + /* + It is not safe to upgrade the metadata lock without GLOBAL IX lock. + This can happen with FLUSH TABLES WITH READ LOCK as we in these + cases don't take a GLOBAL IX lock in order to be compatible with + global read lock. + */ + if (!thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", + MDL_INTENTION_EXCLUSIVE)) { - while (tab->mdl_ticket != NULL && - !tab->mdl_ticket->is_upgradable_or_exclusive() && - (tab= find_locked_table(tab->next, db, table_name))) - continue; - if (!tab) - { - if (!no_error) - my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name); - return 0; - } + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name); + return NULL; } + + while (tab->mdl_ticket != NULL && + !tab->mdl_ticket->is_upgradable_or_exclusive() && + (tab= find_locked_table(tab->next, db, table_name))) + continue; + + if (!tab && !no_error) + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name); + return tab; } @@ -4653,8 +4661,7 @@ open_tables_check_upgradable_mdl(THD *th Note that find_table_for_mdl_upgrade() will report an error if no suitable ticket is found. */ - if (!find_table_for_mdl_upgrade(thd->open_tables, table->db, - table->table_name, FALSE)) + if (!find_table_for_mdl_upgrade(thd, table->db, table->table_name, FALSE)) return TRUE; } } === modified file 'sql/sql_base.h' --- a/sql/sql_base.h 2010-11-11 17:11:05 +0000 +++ b/sql/sql_base.h 2011-03-03 15:45:28 +0000 @@ -290,7 +290,7 @@ bool tdc_open_view(THD *thd, TABLE_LIST char *cache_key, uint cache_key_length, MEM_ROOT *mem_root, uint flags); void tdc_flush_unused_tables(); -TABLE *find_table_for_mdl_upgrade(TABLE *list, const char *db, +TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, const char *table_name, bool no_error); void mark_tmp_table_for_reuse(TABLE *table); === modified file 'sql/sql_reload.cc' --- a/sql/sql_reload.cc 2010-12-07 16:11:13 +0000 +++ b/sql/sql_reload.cc 2011-03-03 15:45:28 +0000 @@ -220,8 +220,7 @@ bool reload_acl_and_cache(THD *thd, unsi if (tables) { for (TABLE_LIST *t= tables; t; t= t->next_local) - if (!find_table_for_mdl_upgrade(thd->open_tables, t->db, - t->table_name, FALSE)) + if (!find_table_for_mdl_upgrade(thd, t->db, t->table_name, false)) return 1; } else === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2011-01-26 13:23:29 +0000 +++ b/sql/sql_table.cc 2011-03-03 15:45:28 +0000 @@ -1917,7 +1917,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST by parser) it is safe to cache pointer to the TABLE instances in its elements. */ - table->table= find_table_for_mdl_upgrade(thd->open_tables, table->db, + table->table= find_table_for_mdl_upgrade(thd, table->db, table->table_name, false); if (!table->table) DBUG_RETURN(true); === modified file 'sql/sql_trigger.cc' --- a/sql/sql_trigger.cc 2010-11-11 17:11:05 +0000 +++ b/sql/sql_trigger.cc 2011-03-03 15:45:28 +0000 @@ -467,8 +467,7 @@ bool mysql_create_or_drop_trigger(THD *t if (thd->locked_tables_mode) { /* Under LOCK TABLES we must only accept write locked tables. */ - if (!(tables->table= find_table_for_mdl_upgrade(thd->open_tables, - tables->db, + if (!(tables->table= find_table_for_mdl_upgrade(thd, tables->db, tables->table_name, FALSE))) goto end; === modified file 'sql/sql_truncate.cc' --- a/sql/sql_truncate.cc 2010-10-29 14:10:53 +0000 +++ b/sql/sql_truncate.cc 2011-03-03 15:45:28 +0000 @@ -327,7 +327,7 @@ bool Truncate_statement::lock_table(THD */ if (thd->locked_tables_mode) { - if (!(table= find_table_for_mdl_upgrade(thd->open_tables, table_ref->db, + if (!(table= find_table_for_mdl_upgrade(thd, table_ref->db, table_ref->table_name, FALSE))) DBUG_RETURN(TRUE); --===============1850890957085875694== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jon.hauglid@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jon.hauglid@stripped # target_branch: file:///export/home/x/mysql-5.5-bug57649/ # testament_sha1: c95d59c0982fcaf43daf8358459cbfe9a54413c8 # timestamp: 2011-03-03 16:45:30 +0100 # base_revision_id: alexander.barkov@stripped\ # 7my9cadoq48gup0z # # Begin bundle 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 0qcfX/xdyRThQkLUctA0 --===============1850890957085875694==--