List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:October 25 2010 3:16pm
Subject:bzr commit into mysql-5.5-runtime branch (kostja:3178) Bug#54673
View as plain text  
#At file:///opt/local/work/5.5-rt-stage/ based on revid:dmitry.lenev@stripped

 3178 Konstantin Osipov	2010-10-25
      Bug#54673, review comments.

    modified:
      mysql-test/r/events_2.result
      mysql-test/suite/perfschema/r/server_init.result
      mysql-test/suite/perfschema/t/server_init.test
      mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result
      mysql-test/t/events_2.test
      sql/event_db_repository.cc
      sql/events.cc
      sql/events.h
      sql/handler.cc
      sql/lock.cc
      sql/lock.h
      sql/mdl.cc
      sql/mdl.h
      sql/mysqld.cc
      sql/sp.cc
      sql/sql_parse.cc
      sql/transaction.cc
=== modified file 'mysql-test/r/events_2.result'
--- a/mysql-test/r/events_2.result	2009-12-22 09:35:56 +0000
+++ b/mysql-test/r/events_2.result	2010-10-25 15:16:12 +0000
@@ -133,15 +133,15 @@ select event_name from information_schem
 event_name
 e1
 create event e2 on schedule every 10 hour do select 1;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 disable;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 rename to e3;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e2;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e1;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 unlock tables;
 lock table t1 write;
 show create event e1;
@@ -151,15 +151,15 @@ select event_name from information_schem
 event_name
 e1
 create event e2 on schedule every 10 hour do select 1;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 disable;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 rename to e3;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e2;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e1;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 unlock tables;
 lock table t1 read, mysql.event read;
 show create event e1;
@@ -169,15 +169,15 @@ select event_name from information_schem
 event_name
 e1
 create event e2 on schedule every 10 hour do select 1;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 disable;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 rename to e3;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e2;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e1;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 unlock tables;
 lock table t1 write, mysql.event read;
 show create event e1;
@@ -187,15 +187,15 @@ select event_name from information_schem
 event_name
 e1
 create event e2 on schedule every 10 hour do select 1;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 disable;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 rename to e3;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e2;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e1;
-ERROR HY000: Table 'event' was locked with a READ lock and can't be updated
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 unlock tables;
 lock table t1 read, mysql.event write;
 ERROR HY000: You can't combine write-locking of system tables with other tables or lock types
@@ -209,11 +209,17 @@ select event_name from information_schem
 event_name
 e1
 create event e2 on schedule every 10 hour do select 1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 disable;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 alter event e2 rename to e3;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e3;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 drop event e1;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 unlock tables;
+drop event e1;
 Make sure we have left no events 
 select event_name from information_schema.events;
 event_name

=== modified file 'mysql-test/suite/perfschema/r/server_init.result'
--- a/mysql-test/suite/perfschema/r/server_init.result	2010-10-18 12:33:49 +0000
+++ b/mysql-test/suite/perfschema/r/server_init.result	2010-10-25 15:16:12 +0000
@@ -116,10 +116,6 @@ where name like "wait/synch/mutex/sql/Qu
 count(name)
 1
 select count(name) from MUTEX_INSTANCES
-where name like "wait/synch/mutex/sql/LOCK_event_metadata";
-count(name)
-1
-select count(name) from MUTEX_INSTANCES
 where name like "wait/synch/mutex/sql/LOCK_event_queue";
 count(name)
 1

=== modified file 'mysql-test/suite/perfschema/t/server_init.test'
--- a/mysql-test/suite/perfschema/t/server_init.test	2010-10-18 12:33:49 +0000
+++ b/mysql-test/suite/perfschema/t/server_init.test	2010-10-25 15:16:12 +0000
@@ -130,9 +130,6 @@ select count(name) from MUTEX_INSTANCES
 #  where name like "wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state";
 
 select count(name) from MUTEX_INSTANCES
- where name like "wait/synch/mutex/sql/LOCK_event_metadata";
-
-select count(name) from MUTEX_INSTANCES
  where name like "wait/synch/mutex/sql/LOCK_event_queue";
 
 select count(name) from MUTEX_INSTANCES

=== modified file 'mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result'
--- a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result	2010-04-28 03:26:47 +0000
+++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result	2010-10-25 15:16:12 +0000
@@ -123,16 +123,16 @@ DROP PROCEDURE p2;
 ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 INSERT INTO t2 VALUES ("DROP PROCEDURE p2 with table locked");
 CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 INSERT INTO t2 VALUES ("CREATE EVENT e1 with table locked");
 UNLOCK TABLE;
 CREATE EVENT e2 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
 LOCK TABLE t1 WRITE;
 ALTER EVENT e2 ON SCHEDULE EVERY 20 HOUR DO SELECT 1;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 INSERT INTO t2 VALUES ("ALTER EVENT e2 with table locked");
 DROP EVENT e2;
-ERROR HY000: Table 'event' was not locked with LOCK TABLES
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 INSERT INTO t2 VALUES ("DROP EVENT e2 with table locked");
 CREATE DATABASE mysqltest1;
 ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction

=== modified file 'mysql-test/t/events_2.test'
--- a/mysql-test/t/events_2.test	2009-12-22 09:35:56 +0000
+++ b/mysql-test/t/events_2.test	2010-10-25 15:16:12 +0000
@@ -212,15 +212,15 @@ lock table t1 read;
 --replace_regex /STARTS '[^']+'/STARTS '#'/
 show create event e1;
 select event_name from information_schema.events;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 create event e2 on schedule every 10 hour do select 1;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 disable;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 rename to e3;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e2;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e1;
 unlock tables;
 #
@@ -229,15 +229,15 @@ lock table t1 write;
 --replace_regex /STARTS '[^']+'/STARTS '#'/
 show create event e1;
 select event_name from information_schema.events;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 create event e2 on schedule every 10 hour do select 1;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 disable;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 rename to e3;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e2;
---error ER_TABLE_NOT_LOCKED
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e1;
 unlock tables;
 #
@@ -246,15 +246,15 @@ lock table t1 read, mysql.event read;
 --replace_regex /STARTS '[^']+'/STARTS '#'/
 show create event e1;
 select event_name from information_schema.events;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 create event e2 on schedule every 10 hour do select 1;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 disable;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 rename to e3;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e2;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e1;
 unlock tables;
 #
@@ -263,15 +263,15 @@ lock table t1 write, mysql.event read;
 --replace_regex /STARTS '[^']+'/STARTS '#'/
 show create event e1;
 select event_name from information_schema.events;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 create event e2 on schedule every 10 hour do select 1;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 disable;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 rename to e3;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e2;
---error ER_TABLE_NOT_LOCKED_FOR_WRITE
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e1;
 unlock tables;
 #
@@ -285,12 +285,18 @@ lock table mysql.event write;
 --replace_regex /STARTS '[^']+'/STARTS '#'/
 show create event e1;
 select event_name from information_schema.events;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 create event e2 on schedule every 10 hour do select 1;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 disable;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 alter event e2 rename to e3;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e3;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
 drop event e1;
 unlock tables;
+drop event e1;
 --echo Make sure we have left no events 
 select event_name from information_schema.events;
 --echo

=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2010-08-13 08:02:37 +0000
+++ b/sql/event_db_repository.cc	2010-10-25 15:16:12 +0000
@@ -622,6 +622,12 @@ Event_db_repository::create_event(THD *t
   TABLE *table= NULL;
   sp_head *sp= thd->lex->sphead;
   ulong saved_mode= thd->variables.sql_mode;
+  /*
+    Take a savepoint to release only the lock on mysql.event
+    table at the end but keep the global read lock and
+    possible other locks taken by the caller.
+  */
+  MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint();
 
   DBUG_ENTER("Event_db_repository::create_event");
 
@@ -699,8 +705,8 @@ Event_db_repository::create_event(THD *t
   ret= 0;
 
 end:
-  if (table)
-    close_mysql_tables(thd);
+  close_thread_tables(thd);
+  thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
 
   thd->variables.sql_mode= saved_mode;
   DBUG_RETURN(test(ret));
@@ -734,6 +740,12 @@ Event_db_repository::update_event(THD *t
   TABLE *table= NULL;
   sp_head *sp= thd->lex->sphead;
   ulong saved_mode= thd->variables.sql_mode;
+  /*
+    Take a savepoint to release only the lock on mysql.event
+    table at the end but keep the global read lock and
+    possible other locks taken by the caller.
+  */
+  MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint();
   int ret= 1;
 
   DBUG_ENTER("Event_db_repository::update_event");
@@ -811,8 +823,8 @@ Event_db_repository::update_event(THD *t
   ret= 0;
 
 end:
-  if (table)
-    close_mysql_tables(thd);
+  close_thread_tables(thd);
+  thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
 
   thd->variables.sql_mode= saved_mode;
   DBUG_RETURN(test(ret));
@@ -838,6 +850,12 @@ Event_db_repository::drop_event(THD *thd
                                 bool drop_if_exists)
 {
   TABLE *table= NULL;
+  MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint();
+  /*
+    Take a savepoint to release only the lock on mysql.event
+    table at the end but keep the global read lock and
+    possible other locks taken by the caller.
+  */
   int ret= 1;
 
   DBUG_ENTER("Event_db_repository::drop_event");
@@ -866,8 +884,8 @@ Event_db_repository::drop_event(THD *thd
   ret= 0;
 
 end:
-  if (table)
-    close_mysql_tables(thd);
+  close_thread_tables(thd);
+  thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
 
   DBUG_RETURN(test(ret));
 }

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2010-08-26 10:01:43 +0000
+++ b/sql/events.cc	2010-10-25 15:16:12 +0000
@@ -30,6 +30,7 @@
 #include "event_scheduler.h"
 #include "sp_head.h" // for Stored_program_creation_ctx
 #include "set_var.h"
+#include "lock.h"   // lock_object_name
 
 /**
   @addtogroup Event_Scheduler
@@ -77,7 +78,6 @@ Event_queue *Events::event_queue;
 Event_scheduler *Events::scheduler;
 Event_db_repository *Events::db_repository;
 ulong Events::opt_event_scheduler= Events::EVENTS_OFF;
-mysql_mutex_t Events::LOCK_event_metadata;
 bool Events::check_system_tables_error= FALSE;
 
 
@@ -340,7 +340,9 @@ Events::create_event(THD *thd, Event_par
   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
     thd->clear_current_stmt_binlog_format_row();
 
-  mysql_mutex_lock(&LOCK_event_metadata);
+  if (lock_object_name(thd, MDL_key::EVENT,
+                       parse_data->dbname.str, parse_data->name.str))
+    DBUG_RETURN(TRUE);
 
   /* On error conditions my_error() is called so no need to handle here */
   if (!(ret= db_repository->create_event(thd, parse_data, if_not_exists)))
@@ -388,7 +390,6 @@ Events::create_event(THD *thd, Event_par
       }
     }
   }
-  mysql_mutex_unlock(&LOCK_event_metadata);
   /* Restore the state of binlog format */
   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
   if (save_binlog_row_based)
@@ -472,7 +473,9 @@ Events::update_event(THD *thd, Event_par
   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
     thd->clear_current_stmt_binlog_format_row();
 
-  mysql_mutex_lock(&LOCK_event_metadata);
+  if (lock_object_name(thd, MDL_key::EVENT,
+                       parse_data->dbname.str, parse_data->name.str))
+    DBUG_RETURN(TRUE);
 
   /* On error conditions my_error() is called so no need to handle here */
   if (!(ret= db_repository->update_event(thd, parse_data,
@@ -502,7 +505,6 @@ Events::update_event(THD *thd, Event_par
       ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
     }
   }
-  mysql_mutex_unlock(&LOCK_event_metadata);
   /* Restore the state of binlog format */
   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
   if (save_binlog_row_based)
@@ -556,7 +558,9 @@ Events::drop_event(THD *thd, LEX_STRING 
   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
     thd->clear_current_stmt_binlog_format_row();
 
-  mysql_mutex_lock(&LOCK_event_metadata);
+  if (lock_object_name(thd, MDL_key::EVENT,
+                       dbname.str, name.str))
+    DBUG_RETURN(TRUE);
   /* On error conditions my_error() is called so no need to handle here */
   if (!(ret= db_repository->drop_event(thd, dbname, name, if_exists)))
   {
@@ -566,7 +570,6 @@ Events::drop_event(THD *thd, LEX_STRING 
     DBUG_ASSERT(thd->query() && thd->query_length());
     ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
   }
-  mysql_mutex_unlock(&LOCK_event_metadata);
   /* Restore the state of binlog format */
   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
   if (save_binlog_row_based)
@@ -595,15 +598,12 @@ Events::drop_schema_events(THD *thd, cha
   DBUG_PRINT("enter", ("dropping events from %s", db));
 
   /*
-    sic: no check if the scheduler is disabled or system tables
+    Sic: no check if the scheduler is disabled or system tables
     are damaged, as intended.
   */
-
-  mysql_mutex_lock(&LOCK_event_metadata);
   if (event_queue)
     event_queue->drop_schema_events(thd, db_lex);
   db_repository->drop_schema_events(thd, db_lex);
-  mysql_mutex_unlock(&LOCK_event_metadata);
 
   DBUG_VOID_RETURN;
 }
@@ -915,12 +915,11 @@ Events::deinit()
 }
 
 #ifdef HAVE_PSI_INTERFACE
-PSI_mutex_key key_LOCK_event_metadata, key_LOCK_event_queue,
+PSI_mutex_key key_LOCK_event_queue,
               key_event_scheduler_LOCK_scheduler_state;
 
 static PSI_mutex_info all_events_mutexes[]=
 {
-  { &key_LOCK_event_metadata, "LOCK_event_metadata", PSI_FLAG_GLOBAL},
   { &key_LOCK_event_queue, "LOCK_event_queue", PSI_FLAG_GLOBAL},
   { &key_event_scheduler_LOCK_scheduler_state, "Event_scheduler::LOCK_scheduler_state", PSI_FLAG_GLOBAL}
 };
@@ -974,23 +973,6 @@ Events::init_mutexes()
 #ifdef HAVE_PSI_INTERFACE
   init_events_psi_keys();
 #endif
-
-  mysql_mutex_init(key_LOCK_event_metadata,
-                   &LOCK_event_metadata, MY_MUTEX_INIT_FAST);
-}
-
-
-/*
-  Destroys Events mutexes
-
-  SYNOPSIS
-    Events::destroy_mutexes()
-*/
-
-void
-Events::destroy_mutexes()
-{
-  mysql_mutex_destroy(&LOCK_event_metadata);
 }
 
 

=== modified file 'sql/events.h'
--- a/sql/events.h	2010-08-26 10:01:43 +0000
+++ b/sql/events.h	2010-10-25 15:16:12 +0000
@@ -26,8 +26,7 @@
 */
 
 #ifdef HAVE_PSI_INTERFACE
-extern PSI_mutex_key key_LOCK_event_metadata,
-                     key_event_scheduler_LOCK_scheduler_state;
+extern PSI_mutex_key key_event_scheduler_LOCK_scheduler_state;
 extern PSI_cond_key key_event_scheduler_COND_state;
 extern PSI_thread_key key_thread_event_scheduler, key_thread_event_worker;
 #endif /* HAVE_PSI_INTERFACE */
@@ -79,7 +78,6 @@ public:
   enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED };
   /* Protected using LOCK_global_system_variables only. */
   static ulong opt_event_scheduler;
-  static mysql_mutex_t LOCK_event_metadata;
   static bool check_if_system_tables_error();
   static bool start();
   static bool stop();

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2010-10-22 07:16:34 +0000
+++ b/sql/handler.cc	2010-10-25 15:16:12 +0000
@@ -1241,7 +1241,14 @@ int ha_commit_trans(THD *thd, bool all)
     RUN_HOOK(transaction, after_commit, (thd, FALSE));
 end:
     if (rw_trans && mdl_request.ticket)
+    {
+      /*
+        Even though all metadata locks are normally released after
+        COMMIT, here we play safe and release the commit blocker
+        lock as soon as it's not needed.
+      */
       thd->mdl_context.release_lock(mdl_request.ticket);
+    }
   }
   /* Free resources and perform other cleanup even for 'empty' transactions. */
   else if (is_real_trans)

=== modified file 'sql/lock.cc'
--- a/sql/lock.cc	2010-10-22 07:16:34 +0000
+++ b/sql/lock.cc	2010-10-25 15:16:12 +0000
@@ -805,13 +805,13 @@ bool lock_schema_name(THD *thd, const ch
 
 
 /**
-  Obtain an exclusive metadata lock on the stored routine name.
+  Obtain an exclusive metadata lock on an object name.
 
   @param thd         Thread handle.
-  @param is_function Stored routine type (only functions or procedures
-                     are name-locked.
-  @param db          The schema the routine belongs to.
-  @param name        Routine name.
+  @param mdl_type    Object type (currently functions, procedures
+                     and events can be name-locked).
+  @param db          The schema the object belongs to.
+  @param name        Object name in the schema.
 
   This function assumes that no metadata locks were acquired
   before calling it. Additionally, it cannot be called while
@@ -827,12 +827,9 @@ bool lock_schema_name(THD *thd, const ch
                  or this connection was killed.
 */
 
-bool lock_routine_name(THD *thd, bool is_function,
+bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type,
                        const char *db, const char *name)
 {
-  MDL_key::enum_mdl_namespace mdl_type= (is_function ?
-                                         MDL_key::FUNCTION :
-                                         MDL_key::PROCEDURE);
   MDL_request_list mdl_requests;
   MDL_request global_request;
   MDL_request schema_request;

=== modified file 'sql/lock.h'
--- a/sql/lock.h	2010-10-18 12:33:49 +0000
+++ b/sql/lock.h	2010-10-25 15:16:12 +0000
@@ -2,6 +2,7 @@
 #define LOCK_INCLUDED
 
 #include "thr_lock.h"                           /* thr_lock_type */
+#include "mdl.h"
 
 // Forward declarations
 struct TABLE;
@@ -21,7 +22,7 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK 
 /* Lock based on name */
 bool lock_schema_name(THD *thd, const char *db);
 /* Lock based on stored routine name */
-bool lock_routine_name(THD *thd, bool is_function, const char *db,
-                       const char *name);
+bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type,
+                      const char *db, const char *name);
 
 #endif /* LOCK_INCLUDED */

=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2010-10-18 12:33:49 +0000
+++ b/sql/mdl.cc	2010-10-25 15:16:12 +0000
@@ -83,7 +83,8 @@ const char *MDL_key::m_namespace_to_wait
   "Waiting for table metadata lock",
   "Waiting for stored function metadata lock",
   "Waiting for stored procedure metadata lock",
-  NULL,
+  "Waiting for trigger metadata lock",
+  "Waiting for event metadata lock",
   "Waiting for global read lock"
 };
 

=== modified file 'sql/mdl.h'
--- a/sql/mdl.h	2010-10-18 12:33:49 +0000
+++ b/sql/mdl.h	2010-10-25 15:16:12 +0000
@@ -167,13 +167,16 @@ class MDL_key
 {
 public:
   /**
-    Object namespaces
+    Object namespaces.
+    Sic: when adding a new member to this enum make sure to
+    update m_namespace_to_wait_state_name array in mdl.cc!
 
     Different types of objects exist in different namespaces
      - TABLE is for tables and views.
      - FUNCTION is for stored functions.
      - PROCEDURE is for stored procedures.
      - TRIGGER is for triggers.
+     - EVENT is for event scheduler events
     Note that although there isn't metadata locking on triggers,
     it's necessary to have a separate namespace for them since
     MDL_key is also used outside of the MDL subsystem.
@@ -184,6 +187,7 @@ public:
                             FUNCTION,
                             PROCEDURE,
                             TRIGGER,
+                            EVENT,
                             COMMIT,
                             /* This should be the last ! */
                             NAMESPACE_END };

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-10-18 12:33:49 +0000
+++ b/sql/mysqld.cc	2010-10-25 15:16:12 +0000
@@ -1540,7 +1540,6 @@ static void clean_up_mutexes()
   mysql_mutex_destroy(&LOCK_crypt);
   mysql_mutex_destroy(&LOCK_user_conn);
   mysql_mutex_destroy(&LOCK_connection_count);
-  Events::destroy_mutexes();
 #ifdef HAVE_OPENSSL
   mysql_mutex_destroy(&LOCK_des_key_file);
 #ifndef HAVE_YASSL

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2010-10-07 16:01:17 +0000
+++ b/sql/sp.cc	2010-10-25 15:16:12 +0000
@@ -27,7 +27,7 @@
 #include "sql_acl.h"                       // SUPER_ACL
 #include "sp_head.h"
 #include "sp_cache.h"
-#include "lock.h"                               // lock_routine_name
+#include "lock.h"                               // lock_object_name
 
 #include <my_user.h>
 
@@ -922,6 +922,8 @@ sp_create_routine(THD *thd, int type, sp
   TABLE *table;
   char definer[USER_HOST_BUFF_SIZE];
   ulong saved_mode= thd->variables.sql_mode;
+  MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
+                                        MDL_key::FUNCTION : MDL_key::PROCEDURE;
 
   CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
 
@@ -941,8 +943,7 @@ sp_create_routine(THD *thd, int type, sp
               type == TYPE_ENUM_FUNCTION);
 
   /* Grab an exclusive MDL lock. */
-  if (lock_routine_name(thd, type == TYPE_ENUM_FUNCTION,
-                        sp->m_db.str, sp->m_name.str))
+  if (lock_object_name(thd, mdl_type, sp->m_db.str, sp->m_name.str))
     DBUG_RETURN(SP_OPEN_TABLE_FAILED);
 
   /* Reset sql_mode during data dictionary operations. */
@@ -1190,6 +1191,8 @@ sp_drop_routine(THD *thd, int type, sp_n
   TABLE *table;
   int ret;
   bool save_binlog_row_based;
+  MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
+                                        MDL_key::FUNCTION : MDL_key::PROCEDURE;
   DBUG_ENTER("sp_drop_routine");
   DBUG_PRINT("enter", ("type: %d  name: %.*s",
 		       type, (int) name->m_name.length, name->m_name.str));
@@ -1198,8 +1201,7 @@ sp_drop_routine(THD *thd, int type, sp_n
               type == TYPE_ENUM_FUNCTION);
 
   /* Grab an exclusive MDL lock. */
-  if (lock_routine_name(thd, type == TYPE_ENUM_FUNCTION,
-                        name->m_db.str, name->m_name.str))
+  if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
     DBUG_RETURN(SP_DELETE_ROW_FAILED);
 
   if (!(table= open_proc_table_for_update(thd)))
@@ -1270,6 +1272,8 @@ sp_update_routine(THD *thd, int type, sp
   TABLE *table;
   int ret;
   bool save_binlog_row_based;
+  MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
+                                        MDL_key::FUNCTION : MDL_key::PROCEDURE;
   DBUG_ENTER("sp_update_routine");
   DBUG_PRINT("enter", ("type: %d  name: %.*s",
 		       type, (int) name->m_name.length, name->m_name.str));
@@ -1278,8 +1282,7 @@ sp_update_routine(THD *thd, int type, sp
               type == TYPE_ENUM_FUNCTION);
 
   /* Grab an exclusive MDL lock. */
-  if (lock_routine_name(thd, type == TYPE_ENUM_FUNCTION,
-                        name->m_db.str, name->m_name.str))
+  if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
     DBUG_RETURN(SP_OPEN_TABLE_FAILED);
 
   if (!(table= open_proc_table_for_update(thd)))

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-10-21 05:43:57 +0000
+++ b/sql/sql_parse.cc	2010-10-25 15:16:12 +0000
@@ -278,12 +278,9 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_DROP_VIEW]=      CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_CREATE_TRIGGER]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_DROP_TRIGGER]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
-  sql_command_flags[SQLCOM_CREATE_EVENT]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS |
-                                            CF_EXPLICIT_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_ALTER_EVENT]=    CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS |
-                                            CF_EXPLICIT_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_DROP_EVENT]=     CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS |
-                                            CF_EXPLICIT_PROTECT_AGAINST_GRL;
+  sql_command_flags[SQLCOM_CREATE_EVENT]=   CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
+  sql_command_flags[SQLCOM_ALTER_EVENT]=    CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
+  sql_command_flags[SQLCOM_DROP_EVENT]=     CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
 
   sql_command_flags[SQLCOM_UPDATE]=	    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
                                             CF_CAN_GENERATE_ROW_EVENTS;

=== modified file 'sql/transaction.cc'
--- a/sql/transaction.cc	2010-10-22 07:16:34 +0000
+++ b/sql/transaction.cc	2010-10-25 15:16:12 +0000
@@ -670,6 +670,11 @@ bool trans_xa_commit(THD *thd)
       res= test(ha_commit_one_phase(thd, 1));
       if (res)
         my_error(ER_XAER_RMERR, MYF(0));
+      /*
+        Even though all metadata locks are normally released after
+        COMMIT, here we play safe and release the commit blocker
+        lock as soon as it's not needed.
+      */
       if (mdl_request.ticket)
         thd->mdl_context.release_lock(mdl_request.ticket);
     }


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20101025151612-7llrt2dsdbrxy2f1.bundle
Thread
bzr commit into mysql-5.5-runtime branch (kostja:3178) Bug#54673Konstantin Osipov25 Oct