From: Jon Olav Hauglid Date: March 3 2011 3:46pm Subject: bzr commit into mysql-5.5 branch (jon.hauglid:3368) Bug#11764779 List-Archive: http://lists.mysql.com/commits/132389 X-Bug: 11764779 Message-Id: <201103031547.p23FlKuM016705@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3849673680478768827==" --===============3849673680478768827== 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 #11764779 (former 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:46:53 +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:46:53 +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:46:53 +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:46:53 +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:46:53 +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:46:53 +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:46:53 +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:46:53 +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); --===============3849673680478768827== 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: 52944a74103045b1d803f8fcf64cd727a49b22b1 # timestamp: 2011-03-03 16:46:56 +0100 # base_revision_id: alexander.barkov@stripped\ # 7my9cadoq48gup0z # # Begin bundle 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 MazcNR5JIpWcBatFqXj8P+LuSKcKEgoSqxDg --===============3849673680478768827==--