List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:August 13 2010 8:02am
Subject:bzr commit into mysql-5.5-bugfixing branch (jon.hauglid:3104) Bug#54105
View as plain text  
#At file:///export/home/x/mysql-5.5-runtime-bug54105/ based on revid:kostja@stripped

 3104 Jon Olav Hauglid	2010-08-13
      Bug #54105 assert in MDL_context::release_locks_stored_before
      
      The problem was that SHOW CREATE EVENT released all metadata locks
      held by the current transaction. This made any exisiting savepoints
      invalid, triggering the assert when ROLLBACK TO SAVEPOINT later
      was executed.
      
      This patch fixes the problem by making sure SHOW CREATE EVENT only
      releases metadata locks acquired by the statement itself.
      
      Test case added to event_trans.test.

    modified:
      mysql-test/r/events_trans.result
      mysql-test/t/events_trans.test
      sql/event_db_repository.cc
      sql/events.cc
=== modified file 'mysql-test/r/events_trans.result'
--- a/mysql-test/r/events_trans.result	2007-10-26 20:40:48 +0000
+++ b/mysql-test/r/events_trans.result	2010-08-13 08:02:37 +0000
@@ -116,3 +116,22 @@ OK: create event: database does not exis
 delete from t1;
 commit work;
 drop database events_test;
+#
+# Bug#54105 assert in MDL_context::release_locks_stored_before
+#
+USE test;
+DROP TABLE IF EXISTS t1, t2;
+DROP EVENT IF EXISTS e1;
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT);
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+SAVEPOINT A;
+SHOW CREATE EVENT e1;
+Event	sql_mode	time_zone	Create Event	character_set_client	collation_connection	Database Collation
+e1		SYSTEM	CREATE DEFINER=`root`@`localhost` EVENT `e1` ON SCHEDULE EVERY 1 DAY STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1	latin1	latin1_swedish_ci	latin1_swedish_ci
+SELECT * FROM t2;
+a
+ROLLBACK WORK TO SAVEPOINT A;
+DROP TABLE t1, t2;

=== modified file 'mysql-test/t/events_trans.test'
--- a/mysql-test/t/events_trans.test	2008-05-09 07:43:02 +0000
+++ b/mysql-test/t/events_trans.test	2010-08-13 08:02:37 +0000
@@ -121,3 +121,28 @@ let $wait_condition=
 
 drop database events_test;
 
+
+--echo #
+--echo # Bug#54105 assert in MDL_context::release_locks_stored_before
+--echo #
+
+USE test;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP EVENT IF EXISTS e1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT);
+CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1;
+
+START TRANSACTION;
+INSERT INTO t1 VALUES (1);
+SAVEPOINT A;
+--replace_regex /STARTS '[^']+'/STARTS '#'/
+SHOW CREATE EVENT e1;
+SELECT * FROM t2;
+ROLLBACK WORK TO SAVEPOINT A;
+
+DROP TABLE t1, t2;

=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2010-07-27 10:25:53 +0000
+++ b/sql/event_db_repository.cc	2010-08-13 08:02:37 +0000
@@ -996,24 +996,33 @@ Event_db_repository::load_named_event(TH
                                       LEX_STRING name, Event_basic *etn)
 {
   bool ret;
-  TABLE *table= NULL;
   ulong saved_mode= thd->variables.sql_mode;
+  Open_tables_backup open_tables_backup;
+  TABLE_LIST event_table;
 
   DBUG_ENTER("Event_db_repository::load_named_event");
   DBUG_PRINT("enter",("thd: 0x%lx  name: %*s", (long) thd,
                       (int) name.length, name.str));
 
+  event_table.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
+
   /* Reset sql_mode during data dictionary operations. */
   thd->variables.sql_mode= 0;
 
-  if (!(ret= open_event_table(thd, TL_READ, &table)))
+  /*
+    We don't use open_event_table() here to make sure that SHOW
+    CREATE EVENT works properly in transactional context, and
+    does not release transactional metadata locks when the
+    event table is closed.
+  */
+  if (!(ret= open_system_tables_for_read(thd, &event_table, &open_tables_backup)))
   {
-    if ((ret= find_named_event(dbname, name, table)))
+    if ((ret= find_named_event(dbname, name, event_table.table)))
       my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name.str);
-    else if ((ret= etn->load_from_row(thd, table)))
+    else if ((ret= etn->load_from_row(thd, event_table.table)))
       my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "event");
 
-    close_mysql_tables(thd);
+    close_system_tables(thd, &open_tables_backup);
   }
 
   thd->variables.sql_mode= saved_mode;

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2010-07-27 10:25:53 +0000
+++ b/sql/events.cc	2010-08-13 08:02:37 +0000
@@ -699,7 +699,6 @@ send_show_create_event(THD *thd, Event_t
 bool
 Events::show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name)
 {
-  Open_tables_backup open_tables_backup;
   Event_timed et;
   bool ret;
 
@@ -722,9 +721,7 @@ Events::show_create_event(THD *thd, LEX_
     deadlock can occur please refer to the description of 'system table'
     flag.
   */
-  thd->reset_n_backup_open_tables_state(&open_tables_backup);
   ret= db_repository->load_named_event(thd, dbname, name, &et);
-  thd->restore_backup_open_tables_state(&open_tables_backup);
 
   if (!ret)
     ret= send_show_create_event(thd, &et, thd->protocol);


Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20100813080237-1b1kez10r2t05cbh.bundle
Thread
bzr commit into mysql-5.5-bugfixing branch (jon.hauglid:3104) Bug#54105Jon Olav Hauglid13 Aug