#At file:///export/home/x/mysql-trunk-test/ based on revid:build@stripped
3730 Jon Olav Hauglid 2011-03-07 [merge]
Merge from mysql-5.5 to mysql-trunk
Text conflict in sql/sql_base.h
Text conflict in sql/sql_trigger.cc
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-07 09:08:10 +0000
@@ -451,3 +451,18 @@ unlock tables;
handler t1 close;
# Cleanup.
drop tables t1, t2;
+#
+# Bug#57649 FLUSH TABLES under FLUSH TABLES <list> 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-07 09:08:10 +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 <list> 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-14 10:28:11 +0000
+++ b/sql/sql_base.cc 2011-03-07 09:23:36 +0000
@@ -1032,7 +1032,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. */
@@ -3126,22 +3126,26 @@ 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
instance were found.
+ @note This function checks if the connection holds a global IX
+ metadata lock. If no such lock is found, it is not safe to
+ upgrade the lock and ER_TABLE_NOT_LOCKED_FOR_WRITE will be
+ reported.
+
@return Pointer to TABLE instance with MDL_SHARED_NO_WRITE,
MDL_SHARED_NO_READ_WRITE, or MDL_EXCLUSIVE metadata
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)
{
@@ -3149,19 +3153,29 @@ 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 a global IX lock.
+ This can happen with FLUSH TABLES <list> 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;
- }
+ if (!no_error)
+ 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;
}
@@ -4660,8 +4674,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-23 22:37:59 +0000
+++ b/sql/sql_base.h 2011-03-07 09:23:36 +0000
@@ -297,7 +297,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-10 16:55:50 +0000
+++ b/sql/sql_reload.cc 2011-03-07 09:23:36 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -221,12 +221,26 @@ 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
{
+ /*
+ It is not safe to upgrade the metadata lock without GLOBAL IX lock.
+ This can happen with FLUSH TABLES <list> 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->open_tables &&
+ !thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "",
+ MDL_INTENTION_EXCLUSIVE))
+ {
+ my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),
+ thd->open_tables->s->table_name.str);
+ return true;
+ }
+
for (TABLE *tab= thd->open_tables; tab; tab= tab->next)
{
if (! tab->mdl_ticket->is_upgradable_or_exclusive())
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2011-02-02 22:02:29 +0000
+++ b/sql/sql_table.cc 2011-03-07 09:23:36 +0000
@@ -2095,7 +2095,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-29 16:27:58 +0000
+++ b/sql/sql_trigger.cc 2011-03-07 09:23:36 +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-11-18 13:50:08 +0000
+++ b/sql/sql_truncate.cc 2011-03-07 09:23:36 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -327,7 +327,7 @@ bool Sql_cmd_truncate_table::lock_table(
*/
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);
No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
| Thread |
|---|
| • bzr commit into mysql-trunk branch (jon.hauglid:3730) | Jon Olav Hauglid | 7 Mar |