List:Commits« Previous MessageNext Message »
From:Dmitry Lenev Date:September 15 2010 9:04pm
Subject:bzr commit into mysql-5.5-runtime branch (dlenev:3139)
View as plain text  
#At file:///home/dlenev/src/bzr/mysql-5.5-rt-pr-open/ based on revid:dlenev@stripped

 3139 Dmitry Lenev	2010-09-16
      Use new rw_pr_lock_t for LOCK_open.
      
      The main goal of this commit is to study performance
      implications of such a step.

    modified:
      mysql-test/suite/perfschema/r/dml_setup_instruments.result
      mysql-test/suite/perfschema/r/func_mutex.result
      mysql-test/suite/perfschema/r/myisam_file_io.result
      mysql-test/suite/perfschema/r/server_init.result
      mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result
      mysql-test/suite/perfschema/r/start_server_on.result
      mysql-test/suite/perfschema/t/func_mutex.test
      mysql-test/suite/perfschema/t/server_init.test
      sql/ha_ndbcluster_binlog.cc
      sql/lock.cc
      sql/mdl.cc
      sql/mdl.h
      sql/sql_admin.cc
      sql/sql_base.cc
      sql/sql_base.h
      sql/sql_handler.cc
      sql/sql_partition.cc
      sql/sql_show.cc
      sql/sql_table.cc
      sql/sql_test.cc
      sql/table.cc
      storage/federated/ha_federated.cc
=== modified file 'mysql-test/suite/perfschema/r/dml_setup_instruments.result'
--- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result	2010-07-27 13:34:58 +0000
+++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result	2010-09-15 21:04:40 +0000
@@ -21,6 +21,7 @@ order by name limit 10;
 NAME	ENABLED	TIMED
 wait/synch/rwlock/sql/LOCK_dboptions	YES	YES
 wait/synch/rwlock/sql/LOCK_grant	YES	YES
+wait/synch/rwlock/sql/LOCK_open	YES	YES
 wait/synch/rwlock/sql/LOCK_system_variables_hash	YES	YES
 wait/synch/rwlock/sql/LOCK_sys_init_connect	YES	YES
 wait/synch/rwlock/sql/LOCK_sys_init_slave	YES	YES
@@ -28,7 +29,6 @@ wait/synch/rwlock/sql/LOGGER::LOCK_logge
 wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for	YES	YES
 wait/synch/rwlock/sql/MDL_lock::rwlock	YES	YES
 wait/synch/rwlock/sql/Query_cache_query::lock	YES	YES
-wait/synch/rwlock/sql/THR_LOCK_servers	YES	YES
 select * from performance_schema.SETUP_INSTRUMENTS
 where name like 'Wait/Synch/Cond/sql/%'
   and name not in (

=== modified file 'mysql-test/suite/perfschema/r/func_mutex.result'
--- a/mysql-test/suite/perfschema/r/func_mutex.result	2010-01-12 01:47:27 +0000
+++ b/mysql-test/suite/perfschema/r/func_mutex.result	2010-09-15 21:04:40 +0000
@@ -14,7 +14,7 @@ id	b
 1	initial value
 SET @before_count = (SELECT SUM(TIMER_WAIT)
 FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 SELECT * FROM t1;
 id	b
 1	initial value
@@ -27,12 +27,12 @@ id	b
 8	initial value
 SET @after_count = (SELECT SUM(TIMER_WAIT)
 FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_timed;
 test_fm1_timed
 Success
 UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO'
-WHERE NAME = 'wait/synch/mutex/sql/LOCK_open';
+WHERE NAME = 'wait/synch/rwlock/sql/LOCK_open';
 TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG;
 TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY;
 TRUNCATE TABLE performance_schema.EVENTS_WAITS_CURRENT;
@@ -41,7 +41,7 @@ id	b
 1	initial value
 SET @before_count = (SELECT SUM(TIMER_WAIT)
 FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 SELECT * FROM t1;
 id	b
 1	initial value
@@ -54,7 +54,7 @@ id	b
 8	initial value
 SET @after_count = (SELECT SUM(TIMER_WAIT)
 FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_timed;
 test_fm2_timed
 Success

=== modified file 'mysql-test/suite/perfschema/r/myisam_file_io.result'
--- a/mysql-test/suite/perfschema/r/myisam_file_io.result	2010-07-16 14:21:07 +0000
+++ b/mysql-test/suite/perfschema/r/myisam_file_io.result	2010-09-15 21:04:40 +0000
@@ -50,7 +50,7 @@ Performance_schema_file_instances_lost	0
 Performance_schema_locker_lost	0
 Performance_schema_mutex_classes_lost	0
 Performance_schema_mutex_instances_lost	0
-Performance_schema_rwlock_classes_lost	0
+Performance_schema_rwlock_classes_lost	1
 Performance_schema_rwlock_instances_lost	0
 Performance_schema_table_handles_lost	0
 Performance_schema_table_instances_lost	0

=== modified file 'mysql-test/suite/perfschema/r/server_init.result'
--- a/mysql-test/suite/perfschema/r/server_init.result	2010-08-12 13:50:23 +0000
+++ b/mysql-test/suite/perfschema/r/server_init.result	2010-09-15 21:04:40 +0000
@@ -39,8 +39,8 @@ select count(name) from COND_INSTANCES
 where name like "wait/synch/cond/mysys/THR_COND_threads";
 count(name)
 1
-select count(name) from MUTEX_INSTANCES
-where name like "wait/synch/mutex/sql/LOCK_open";
+select count(name) from RWLOCK_INSTANCES
+where name like "wait/synch/rwlock/sql/LOCK_open";
 count(name)
 1
 select count(name) from MUTEX_INSTANCES

=== modified file 'mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result'
--- a/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result	2010-09-08 18:01:12 +0000
+++ b/mysql-test/suite/perfschema/r/start_server_no_rwlock_inst.result	2010-09-15 21:04:40 +0000
@@ -63,7 +63,7 @@ count(*) > 0
 1
 show status like "performance_schema_rwlock_classes_lost";
 Variable_name	Value
-Performance_schema_rwlock_classes_lost	0
+Performance_schema_rwlock_classes_lost	1
 show variables like "performance_schema_max_rwlock_instances";
 Variable_name	Value
 performance_schema_max_rwlock_instances	0

=== modified file 'mysql-test/suite/perfschema/r/start_server_on.result'
--- a/mysql-test/suite/perfschema/r/start_server_on.result	2010-09-08 18:01:12 +0000
+++ b/mysql-test/suite/perfschema/r/start_server_on.result	2010-09-15 21:04:40 +0000
@@ -64,7 +64,7 @@ Performance_schema_file_instances_lost	0
 Performance_schema_locker_lost	0
 Performance_schema_mutex_classes_lost	0
 Performance_schema_mutex_instances_lost	0
-Performance_schema_rwlock_classes_lost	0
+Performance_schema_rwlock_classes_lost	1
 Performance_schema_rwlock_instances_lost	0
 Performance_schema_table_handles_lost	0
 Performance_schema_table_instances_lost	0

=== modified file 'mysql-test/suite/perfschema/t/func_mutex.test'
--- a/mysql-test/suite/perfschema/t/func_mutex.test	2010-01-12 01:47:27 +0000
+++ b/mysql-test/suite/perfschema/t/func_mutex.test	2010-09-15 21:04:40 +0000
@@ -54,18 +54,18 @@ SELECT * FROM t1 WHERE id = 1;
 
 SET @before_count = (SELECT SUM(TIMER_WAIT)
                      FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-                     WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+                     WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 
 SELECT * FROM t1;
 
 SET @after_count = (SELECT SUM(TIMER_WAIT)
                     FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-                    WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+                    WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 
 SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_timed;
 
 UPDATE performance_schema.SETUP_INSTRUMENTS SET enabled = 'NO'
-WHERE NAME = 'wait/synch/mutex/sql/LOCK_open';
+WHERE NAME = 'wait/synch/rwlock/sql/LOCK_open';
 
 TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY_LONG;
 TRUNCATE TABLE performance_schema.EVENTS_WAITS_HISTORY;
@@ -75,13 +75,13 @@ SELECT * FROM t1 WHERE id = 1;
 
 SET @before_count = (SELECT SUM(TIMER_WAIT)
                      FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-                     WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+                     WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 
 SELECT * FROM t1;
 
 SET @after_count = (SELECT SUM(TIMER_WAIT)
                     FROM performance_schema.EVENTS_WAITS_HISTORY_LONG
-                    WHERE (EVENT_NAME = 'wait/synch/mutex/sql/LOCK_open'));
+                    WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_open'));
 
 SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_timed;
 

=== modified file 'mysql-test/suite/perfschema/t/server_init.test'
--- a/mysql-test/suite/perfschema/t/server_init.test	2010-08-12 13:50:23 +0000
+++ b/mysql-test/suite/perfschema/t/server_init.test	2010-09-15 21:04:40 +0000
@@ -68,8 +68,8 @@ select count(name) from COND_INSTANCES
 
 # Verify that these global mutexes have been properly initilized in sql
 
-select count(name) from MUTEX_INSTANCES
- where name like "wait/synch/mutex/sql/LOCK_open";
+select count(name) from RWLOCK_INSTANCES
+ where name like "wait/synch/rwlock/sql/LOCK_open";
 
 select count(name) from MUTEX_INSTANCES
  where name like "wait/synch/mutex/sql/LOCK_thread_count";

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-08-12 13:50:23 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2010-09-15 21:04:40 +0000
@@ -375,9 +375,9 @@ ndbcluster_binlog_open_table(THD *thd, N
     free_table_share(table_share);
     DBUG_RETURN(error);
   }
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   assign_new_table_id(table_share);
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   if (!reopen)
   {

=== modified file 'sql/lock.cc'
--- a/sql/lock.cc	2010-08-12 13:50:23 +0000
+++ b/sql/lock.cc	2010-09-15 21:04:40 +0000
@@ -753,7 +753,7 @@ static MYSQL_LOCK *get_lock_data(THD *th
   @param thd         Thread handle.
   @param db          The database name.
 
-  This function cannot be called while holding LOCK_open mutex.
+  This function cannot be called while holding LOCK_open lock.
   To avoid deadlocks, we do not try to obtain exclusive metadata
   locks in LOCK TABLES mode, since in this mode there may be
   other metadata locks already taken by the current connection,
@@ -803,7 +803,7 @@ bool lock_schema_name(THD *thd, const ch
 
   This function assumes that no metadata locks were acquired
   before calling it. Additionally, it cannot be called while
-  holding LOCK_open mutex. Both these invariants are enforced by
+  holding LOCK_open lock. Both these invariants are enforced by
   asserts in MDL_context::acquire_locks().
   To avoid deadlocks, we do not try to obtain exclusive metadata
   locks in LOCK TABLES mode, since in this mode there may be
@@ -1162,7 +1162,7 @@ wait_if_global_read_lock(THD *thd, bool 
     threads could not close their tables. This would make a pretty
     deadlock.
   */
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   mysql_mutex_lock(&LOCK_global_read_lock);
   if ((need_exit_cond= must_wait))

=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2010-08-12 13:50:23 +0000
+++ b/sql/mdl.cc	2010-09-15 21:04:40 +0000
@@ -1385,7 +1385,7 @@ bool MDL_lock::has_pending_conflicting_l
 {
   bool result;
 
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   mysql_prlock_rdlock(&m_rwlock);
   result= (m_waiting.bitmap() & incompatible_granted_types_bitmap()[type]);
@@ -1557,7 +1557,7 @@ MDL_context::try_acquire_lock_impl(MDL_r
 
   /* Don't take chances in production. */
   mdl_request->ticket= NULL;
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   /*
     Check whether the context already holds a shared lock on the object,
@@ -1641,7 +1641,7 @@ MDL_context::clone_ticket(MDL_request *m
 {
   MDL_ticket *ticket;
 
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
   /*
     By submitting mdl_request->type to MDL_ticket::create()
     we effectively downgrade the cloned lock to the level of
@@ -2241,7 +2241,7 @@ void MDL_context::release_lock(MDL_ticke
                                         lock->key.name()));
 
   DBUG_ASSERT(this == ticket->get_ctx());
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   if (ticket == m_trans_sentinel)
     m_trans_sentinel= ++Ticket_list::Iterator(m_tickets, ticket);
@@ -2335,7 +2335,7 @@ void MDL_context::release_all_locks_for_
 
 void MDL_ticket::downgrade_exclusive_lock(enum_mdl_type type)
 {
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   /*
     Do nothing if already downgraded. Used when we FLUSH TABLE under

=== modified file 'sql/mdl.h'
--- a/sql/mdl.h	2010-08-12 13:50:23 +0000
+++ b/sql/mdl.h	2010-09-15 21:04:40 +0000
@@ -385,17 +385,7 @@ public:
 
   virtual bool inspect_edge(MDL_context *dest) = 0;
   virtual ~MDL_wait_for_graph_visitor();
-  MDL_wait_for_graph_visitor() :m_lock_open_count(0) {}
-public:
-  /**
-   XXX, hack: During deadlock search, we may need to
-   inspect TABLE_SHAREs and acquire LOCK_open. Since
-   LOCK_open is not a recursive mutex, count here how many
-   times we "took" it (but only take and release once).
-   Not using a native recursive mutex or rwlock in 5.5 for
-   LOCK_open since it has significant performance impacts.
-  */
-  uint m_lock_open_count;
+  MDL_wait_for_graph_visitor() {}
 };
 
 /**
@@ -801,7 +791,7 @@ extern "C" const char* thd_enter_cond(MY
 extern "C" void thd_exit_cond(MYSQL_THD thd, const char *old_msg);
 
 #ifndef DBUG_OFF
-extern mysql_mutex_t LOCK_open;
+extern mysql_prlock_t LOCK_open;
 #endif
 
 #endif

=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc	2010-08-18 11:29:04 +0000
+++ b/sql/sql_admin.cc	2010-09-15 21:04:40 +0000
@@ -94,18 +94,18 @@ static int prepare_for_repair(THD *thd, 
     has_mdl_lock= TRUE;
 
     hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length);
-    mysql_mutex_lock(&LOCK_open);
+    mysql_prlock_wrlock(&LOCK_open);
     share= get_table_share(thd, table_list, key, key_length, 0,
                            &error, hash_value);
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
     if (share == NULL)
       DBUG_RETURN(0);				// Can't open frm file
 
     if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, FALSE))
     {
-      mysql_mutex_lock(&LOCK_open);
+      mysql_prlock_wrlock(&LOCK_open);
       release_table_share(share);
-      mysql_mutex_unlock(&LOCK_open);
+      mysql_prlock_unlock(&LOCK_open);
       DBUG_RETURN(0);                           // Out of memory
     }
     table= &tmp_table;
@@ -219,9 +219,9 @@ end:
   thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
   if (table == &tmp_table)
   {
-    mysql_mutex_lock(&LOCK_open);
+    mysql_prlock_wrlock(&LOCK_open);
     closefrm(table, 1);				// Free allocated memory
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
   }
   /* In case of a temporary table there will be no metadata lock. */
   if (error && has_mdl_lock)

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-09-15 14:15:31 +0000
+++ b/sql/sql_base.cc	2010-09-15 21:04:40 +0000
@@ -99,11 +99,11 @@ bool No_such_table_error_handler::safely
   TABLE_SHARE object, LRU lists of used TABLEs and used
   TABLE_SHAREs, refresh_version and the table id counter.
 */
-mysql_mutex_t LOCK_open;
+mysql_prlock_t LOCK_open;
 
 #ifdef HAVE_PSI_INTERFACE
-static PSI_mutex_key key_LOCK_open;
-static PSI_mutex_info all_tdc_mutexes[]= {
+static PSI_rwlock_key key_LOCK_open;
+static PSI_rwlock_info all_tdc_rwlocks[]= {
   { &key_LOCK_open, "LOCK_open", PSI_FLAG_GLOBAL }
 };
 
@@ -120,8 +120,8 @@ static void init_tdc_psi_keys(void)
   if (PSI_server == NULL)
     return;
 
-  count= array_elements(all_tdc_mutexes);
-  PSI_server->register_mutex(category, all_tdc_mutexes, count);
+  count= array_elements(all_tdc_rwlocks);
+  PSI_server->register_rwlock(category, all_tdc_rwlocks, count);
 }
 #endif /* HAVE_PSI_INTERFACE */
 
@@ -280,7 +280,7 @@ extern "C" uchar *table_def_key(const uc
 static void table_def_free_entry(TABLE_SHARE *share)
 {
   DBUG_ENTER("table_def_free_entry");
-  mysql_mutex_assert_owner(&LOCK_open);
+  mysql_prlock_assert_write_owner(&LOCK_open);
   if (share->prev)
   {
     /* remove from old_unused_share list */
@@ -298,7 +298,7 @@ bool table_def_init(void)
 #ifdef HAVE_PSI_INTERFACE
   init_tdc_psi_keys();
 #endif
-  mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST);
+  mysql_prlock_init(key_LOCK_open, &LOCK_open);
   oldest_unused_share= &end_of_unused_share;
   end_of_unused_share.prev= &oldest_unused_share;
 
@@ -319,7 +319,7 @@ void table_def_start_shutdown(void)
 {
   if (table_def_inited)
   {
-    mysql_mutex_lock(&LOCK_open);
+    mysql_prlock_wrlock(&LOCK_open);
     /*
       Ensure that TABLE and TABLE_SHARE objects which are created for
       tables that are open during process of plugins' shutdown are
@@ -327,7 +327,7 @@ void table_def_start_shutdown(void)
       plugins minimal and allows shutdown to proceed smoothly.
     */
     table_def_shutdown_in_progress= TRUE;
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
     /* Free all cached but unused TABLEs and TABLE_SHAREs. */
     close_cached_tables(NULL, NULL, FALSE, LONG_TIMEOUT);
   }
@@ -342,7 +342,7 @@ void table_def_free(void)
     table_def_inited= 0;
     /* Free table definitions. */
     my_hash_free(&table_def_cache);
-    mysql_mutex_destroy(&LOCK_open);
+    mysql_prlock_destroy(&LOCK_open);
   }
   DBUG_VOID_RETURN;
 }
@@ -704,7 +704,7 @@ void release_table_share(TABLE_SHARE *sh
               (ulong) share, share->db.str, share->table_name.str,
               share->ref_count, share->version));
 
-  mysql_mutex_assert_owner(&LOCK_open);
+  mysql_prlock_assert_write_owner(&LOCK_open);
 
   DBUG_ASSERT(share->ref_count);
   if (!--share->ref_count)
@@ -752,7 +752,7 @@ TABLE_SHARE *get_cached_table_share(cons
   char key[NAME_LEN*2+2];
   TABLE_LIST table_list;
   uint key_length;
-  mysql_mutex_assert_owner(&LOCK_open);
+  mysql_prlock_assert_write_owner(&LOCK_open);
 
   table_list.db= (char*) db;
   table_list.table_name= (char*) table_name;
@@ -787,7 +787,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *t
   TABLE_LIST table_list;
   DBUG_ENTER("list_open_tables");
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_rdlock(&LOCK_open);
   bzero((char*) &table_list,sizeof(table_list));
   start_list= &open_list;
   open_list=0;
@@ -827,7 +827,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *t
     start_list= &(*start_list)->next;
     *start_list=0;
   }
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   DBUG_RETURN(open_list);
 }
 
@@ -896,7 +896,7 @@ void free_io_cache(TABLE *table)
 
    @param share Table share.
 
-   @pre Caller should have LOCK_open mutex.
+   @pre Caller should have LOCK_open lock write locked.
 */
 
 static void kill_delayed_threads_for_table(TABLE_SHARE *share)
@@ -904,7 +904,7 @@ static void kill_delayed_threads_for_tab
   I_P_List_iterator<TABLE, TABLE_share> it(share->used_tables);
   TABLE *tab;
 
-  mysql_mutex_assert_owner(&LOCK_open);
+  mysql_prlock_assert_write_owner(&LOCK_open);
 
   while ((tab= it++))
   {
@@ -955,7 +955,7 @@ bool close_cached_tables(THD *thd, TABLE
   DBUG_ENTER("close_cached_tables");
   DBUG_ASSERT(thd || (!wait_for_refresh && !tables));
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   if (!tables)
   {
     /*
@@ -1001,7 +1001,7 @@ bool close_cached_tables(THD *thd, TABLE
       wait_for_refresh=0;			// Nothing to wait for
   }
 
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   if (!wait_for_refresh)
     DBUG_RETURN(result);
@@ -1056,7 +1056,7 @@ bool close_cached_tables(THD *thd, TABLE
     mysql_ha_flush(thd);
     DEBUG_SYNC(thd, "after_flush_unlock");
 
-    mysql_mutex_lock(&LOCK_open);
+    mysql_prlock_wrlock(&LOCK_open);
 
     if (!tables)
     {
@@ -1092,13 +1092,13 @@ bool close_cached_tables(THD *thd, TABLE
       if (share->wait_for_old_version(thd, &abstime,
                                     MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DDL))
       {
-        mysql_mutex_unlock(&LOCK_open);
+        mysql_prlock_unlock(&LOCK_open);
         result= TRUE;
         goto err_with_reopen;
       }
     }
 
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
   }
 
 err_with_reopen:
@@ -1137,7 +1137,7 @@ bool close_cached_connection_tables(THD 
 
   bzero(&tmp, sizeof(TABLE_LIST));
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_rdlock(&LOCK_open);
 
   for (idx= 0; idx < table_def_cache.records; idx++)
   {
@@ -1165,7 +1165,7 @@ bool close_cached_connection_tables(THD 
     tables= (TABLE_LIST *) memdup_root(thd->mem_root, (char*)&tmp, 
                                        sizeof(TABLE_LIST));
   }
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   if (tables)
     result= close_cached_tables(thd, tables, FALSE, LONG_TIMEOUT);
@@ -1287,7 +1287,7 @@ static void close_open_tables(THD *thd)
 {
   bool found_old_table= 0;
 
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables));
 
@@ -1332,7 +1332,7 @@ close_all_tables_for_name(THD *thd, TABL
 
   memcpy(key, share->table_cache_key.str, key_length);
 
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
   for (TABLE **prev= &thd->open_tables; *prev; )
   {
     TABLE *table= *prev;
@@ -1525,7 +1525,7 @@ bool close_thread_table(THD *thd, TABLE 
   DBUG_ENTER("close_thread_table");
   DBUG_ASSERT(table->key_read == 0);
   DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
   /*
     The metadata lock must be released after giving back
     the table to the table cache.
@@ -1549,7 +1549,7 @@ bool close_thread_table(THD *thd, TABLE 
     table->file->ha_reset();
   }
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
 
   if (table->s->has_old_version() || table->needs_reopen() ||
       table_def_shutdown_in_progress)
@@ -1568,7 +1568,7 @@ bool close_thread_table(THD *thd, TABLE 
     if (table_cache_count > table_cache_size)
       free_cache_entry(unused_tables);
   }
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   DBUG_RETURN(found_old_table);
 }
 
@@ -2315,9 +2315,9 @@ bool check_if_table_exists(THD *thd, TAB
               is_lock_owner(MDL_key::TABLE, table->db,
                             table->table_name, MDL_SHARED));
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   share= get_cached_table_share(table->db, table->table_name);
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   if (share)
     goto end;
@@ -2550,7 +2550,7 @@ tdc_wait_for_old_version(THD *thd, const
   TABLE_SHARE *share;
   bool res= FALSE;
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   if ((share= get_cached_table_share(db, table_name)) &&
       share->has_old_version())
   {
@@ -2558,7 +2558,7 @@ tdc_wait_for_old_version(THD *thd, const
     set_timespec(abstime, wait_timeout);
     res= share->wait_for_old_version(thd, &abstime, deadlock_weight);
   }
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   return res;
 }
 
@@ -2862,14 +2862,14 @@ bool open_table(THD *thd, TABLE_LIST *ta
 
 retry_share:
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
 
   if (!(share= get_table_share_with_discover(thd, table_list, key,
                                              key_length, OPEN_VIEW,
                                              &error,
                                              hash_value)))
   {
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
     /*
       If thd->is_error() is not set, we either need discover
       (error == 7), or the error was silenced by the prelocking
@@ -2919,7 +2919,7 @@ retry_share:
 
     DBUG_ASSERT(table_list->view);
 
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
     DBUG_RETURN(FALSE);
   }
 
@@ -2950,7 +2950,7 @@ retry_share:
       bool wait_result;
 
       release_table_share(share);
-      mysql_mutex_unlock(&LOCK_open);
+      mysql_prlock_unlock(&LOCK_open);
 
       thd->push_internal_handler(&mdl_deadlock_handler);
       wait_result= tdc_wait_for_old_version(thd, table_list->db,
@@ -2974,7 +2974,7 @@ retry_share:
         changed only during FLUSH TABLES.
       */
       release_table_share(share);
-      mysql_mutex_unlock(&LOCK_open);
+      mysql_prlock_unlock(&LOCK_open);
       (void)ot_ctx->request_backoff_action(Open_table_context::OT_REOPEN_TABLES,
                                            NULL);
       DBUG_RETURN(TRUE);
@@ -2994,7 +2994,7 @@ retry_share:
     while (table_cache_count > table_cache_size && unused_tables)
       free_cache_entry(unused_tables);
 
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
 
     /* make a new table */
     if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
@@ -3030,12 +3030,12 @@ retry_share:
       goto err_lock;
     }
 
-    mysql_mutex_lock(&LOCK_open);
+    mysql_prlock_wrlock(&LOCK_open);
     /* Add table to the share's used tables list. */
     table_def_add_used_table(thd, table);
   }
 
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   table->mdl_ticket= mdl_ticket;
 
@@ -3053,10 +3053,10 @@ retry_share:
   DBUG_RETURN(FALSE);
 
 err_lock:
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
 err_unlock:
   release_table_share(share);
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   DBUG_RETURN(TRUE);
 }
@@ -3477,7 +3477,7 @@ Locked_tables_list::reopen_tables(THD *t
   PRE-CONDITION(S)
 
     share is non-NULL
-    The LOCK_open mutex is locked.
+    The LOCK_open lock is locked for write.
 
   POST-CONDITION(S)
 
@@ -3498,7 +3498,7 @@ void assign_new_table_id(TABLE_SHARE *sh
 
   /* Preconditions */
   DBUG_ASSERT(share != NULL);
-  mysql_mutex_assert_owner(&LOCK_open);
+  mysql_prlock_assert_write_owner(&LOCK_open);
 
   ulong tid= ++last_table_id;                   /* get next id */
   /*
@@ -3676,7 +3676,7 @@ bool tdc_open_view(THD *thd, TABLE_LIST 
 
   hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key,
                            cache_key_length);
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
 
   if (!(share= get_table_share(thd, table_list, cache_key,
                                cache_key_length,
@@ -3693,14 +3693,14 @@ bool tdc_open_view(THD *thd, TABLE_LIST 
                     mem_root))
   {
     release_table_share(share);
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
     return FALSE;
   }
 
   my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str, "VIEW");
   release_table_share(share);
 err:
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   return TRUE;
 }
 
@@ -3781,7 +3781,7 @@ static bool auto_repair_table(THD *thd, 
 
   hash_value= my_calc_hash(&table_def_cache, (uchar*) cache_key,
                            cache_key_length);
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
 
   if (!(share= get_table_share(thd, table_list, cache_key,
                                cache_key_length,
@@ -3800,7 +3800,7 @@ static bool auto_repair_table(THD *thd, 
     release_table_share(share);
     goto end_unlock;
   }
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   if (open_table_from_share(thd, share, table_list->alias,
                             (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
@@ -3827,14 +3827,14 @@ static bool auto_repair_table(THD *thd, 
   }
   my_free(entry);
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   release_table_share(share);
   /* Remove the repaired share from the table cache. */
   tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
                    table_list->db, table_list->table_name,
                    TRUE);
 end_unlock:
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   return result;
 }
 
@@ -8610,10 +8610,10 @@ my_bool mysql_rm_tmp_tables(void)
 
 void tdc_flush_unused_tables()
 {
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   while (unused_tables)
     free_cache_entry(unused_tables);
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 }
 
 
@@ -8707,7 +8707,7 @@ bool mysql_notify_thread_having_shared_l
                                                 remove TABLE_SHARE).
    @param  db           Name of database
    @param  table_name   Name of table
-   @param  has_lock     If TRUE, LOCK_open is already acquired
+   @param  has_lock     If TRUE, LOCK_open is already locked for write
 
    @note It assumes that table instances are already not used by any
    (other) thread (this should be achieved by using meta-data locks).
@@ -8723,10 +8723,10 @@ void tdc_remove_table(THD *thd, enum_tdc
   TABLE_SHARE *share;
 
   if (! has_lock)
-    mysql_mutex_lock(&LOCK_open);
+    mysql_prlock_wrlock(&LOCK_open);
   else
   {
-    mysql_mutex_assert_owner(&LOCK_open);
+    mysql_prlock_assert_write_owner(&LOCK_open);
   }
 
   DBUG_ASSERT(remove_type == TDC_RT_REMOVE_UNUSED ||
@@ -8777,7 +8777,7 @@ void tdc_remove_table(THD *thd, enum_tdc
   }
 
   if (! has_lock)
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
 }
 
 

=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h	2010-09-15 14:15:31 +0000
+++ b/sql/sql_base.h	2010-09-15 21:04:40 +0000
@@ -69,7 +69,7 @@ enum enum_tdc_remove_table_type {TDC_RT_
 #define RTFC_CHECK_KILLED_FLAG      0x0004
 
 bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
-extern mysql_mutex_t LOCK_open;
+extern mysql_prlock_t LOCK_open;
 bool table_cache_init(void);
 void table_cache_free(void);
 bool table_def_init(void);

=== modified file 'sql/sql_handler.cc'
--- a/sql/sql_handler.cc	2010-08-12 13:50:23 +0000
+++ b/sql/sql_handler.cc	2010-09-15 21:04:40 +0000
@@ -914,7 +914,7 @@ void mysql_ha_flush(THD *thd)
   TABLE_LIST *hash_tables;
   DBUG_ENTER("mysql_ha_flush");
 
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   /*
     Don't try to flush open HANDLERs when we're working with

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2010-08-20 17:15:48 +0000
+++ b/sql/sql_partition.cc	2010-09-15 21:04:40 +0000
@@ -6321,7 +6321,7 @@ static int alter_close_tables(ALTER_PART
     We must keep LOCK_open while manipulating with thd->open_tables.
     Another thread may be working on it.
   */
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   /*
     We can safely remove locks for all tables with the same name:
     later they will all be closed anyway in
@@ -6346,7 +6346,7 @@ static int alter_close_tables(ALTER_PART
                        table->s->table_name.str, TRUE);
     }
   }
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   DBUG_RETURN(0);
 }
 

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2010-08-30 14:07:40 +0000
+++ b/sql/sql_show.cc	2010-09-15 21:04:40 +0000
@@ -3321,7 +3321,7 @@ static int fill_schema_table_from_frm(TH
 
   key_length= create_table_def_key(thd, key, &table_list, 0);
   hash_value= my_calc_hash(&table_def_cache, (uchar*) key, key_length);
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   share= get_table_share(thd, &table_list, key,
                          key_length, OPEN_VIEW, &not_used, hash_value);
   if (!share)
@@ -3381,7 +3381,7 @@ end_share:
   release_table_share(share);
 
 end_unlock:
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   /*
     Don't release the MDL lock, it can be part of a transaction.
     If it is not, it will be released by the call to

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-09-03 07:42:51 +0000
+++ b/sql/sql_table.cc	2010-09-15 21:04:40 +0000
@@ -4107,14 +4107,14 @@ bool mysql_create_table_no_lock(THD *thd
       Then she could create the table. This case is pretty obscure and
       therefore we don't introduce a new error message only for it.
     */
-    mysql_mutex_lock(&LOCK_open);
+    mysql_prlock_wrlock(&LOCK_open);
     if (get_cached_table_share(db, table_name))
     {
-      mysql_mutex_unlock(&LOCK_open);
+      mysql_prlock_unlock(&LOCK_open);
       my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
       goto err;
     }
-    mysql_mutex_unlock(&LOCK_open);
+    mysql_prlock_unlock(&LOCK_open);
   }
 
   /*

=== modified file 'sql/sql_test.cc'
--- a/sql/sql_test.cc	2010-08-04 16:29:13 +0000
+++ b/sql/sql_test.cc	2010-09-15 21:04:40 +0000
@@ -84,7 +84,7 @@ static void print_cached_tables(void)
   compile_time_assert(TL_WRITE_ONLY+1 == array_elements(lock_descriptions));
 
   /* purecov: begin tested */
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
   puts("DB             Table                            Version  Thread  Open  Lock");
 
   for (idx=unused=0 ; idx < table_def_cache.records ; idx++)
@@ -131,7 +131,7 @@ static void print_cached_tables(void)
   if (my_hash_check(&table_def_cache))
     printf("Error: Table definition hash table is corrupted\n");
   fflush(stdout);
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
   /* purecov: end */
   return;
 }

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2010-08-31 09:49:48 +0000
+++ b/sql/table.cc	2010-09-15 21:04:40 +0000
@@ -319,7 +319,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIS
       example, ha_create_table... functions), we do not assign a table
       map id here.  Instead we assign a value that is not used
       elsewhere, and then assign a table map id inside open_table()
-      under the protection of the LOCK_open mutex.
+      under the protection of the LOCK_open lock.
     */
     share->table_map_id= ~0UL;
     share->cached_row_logging_check= -1;
@@ -465,7 +465,7 @@ void free_table_share(TABLE_SHARE *share
       We're about to iterate over a list that is used
       concurrently. Make sure this never happens without a lock.
     */
-    mysql_mutex_assert_owner(&LOCK_open);
+    mysql_prlock_assert_write_owner(&LOCK_open);
 
     while ((ticket= it++))
       (void) ticket->get_ctx()->m_wait.set_status(MDL_wait::GRANTED);
@@ -3080,12 +3080,8 @@ bool TABLE_SHARE::visit_subgraph(Wait_fo
   /*
     To protect used_tables list from being concurrently modified
     while we are iterating through it we acquire LOCK_open.
-    This does not introduce deadlocks in the deadlock detector
-    because we won't try to acquire LOCK_open while
-    holding a write-lock on MDL_lock::m_rwlock.
   */
-  if (gvisitor->m_lock_open_count++ == 0)
-    mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_rdlock(&LOCK_open);
 
   I_P_List_iterator <TABLE, TABLE_share> tables_it(used_tables);
 
@@ -3126,8 +3122,7 @@ end_leave_node:
   gvisitor->leave_node(src_ctx);
 
 end:
-  if (gvisitor->m_lock_open_count-- == 1)
-    mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   return result;
 }
@@ -3157,7 +3152,7 @@ bool TABLE_SHARE::wait_for_old_version(T
   Wait_for_flush ticket(mdl_context, this, deadlock_weight);
   MDL_wait::enum_wait_status wait_status;
 
-  mysql_mutex_assert_owner(&LOCK_open);
+  mysql_prlock_assert_write_owner(&LOCK_open);
   /*
     We should enter this method only when share's version is not
     up to date and the share is referenced. Otherwise our
@@ -3169,7 +3164,7 @@ bool TABLE_SHARE::wait_for_old_version(T
 
   mdl_context->m_wait.reset_status();
 
-  mysql_mutex_unlock(&LOCK_open);
+  mysql_prlock_unlock(&LOCK_open);
 
   mdl_context->will_wait_for(&ticket);
 
@@ -3180,7 +3175,7 @@ bool TABLE_SHARE::wait_for_old_version(T
 
   mdl_context->done_waiting_for();
 
-  mysql_mutex_lock(&LOCK_open);
+  mysql_prlock_wrlock(&LOCK_open);
 
   m_flush_tickets.remove(&ticket);
 

=== modified file 'storage/federated/ha_federated.cc'
--- a/storage/federated/ha_federated.cc	2010-07-23 20:17:55 +0000
+++ b/storage/federated/ha_federated.cc	2010-09-15 21:04:40 +0000
@@ -3140,7 +3140,7 @@ int ha_federated::real_connect()
     to establish Federated connection to guard against a trivial
     Denial of Service scenerio.
   */
-  mysql_mutex_assert_not_owner(&LOCK_open);
+  mysql_prlock_assert_not_write_owner(&LOCK_open);
 
   DBUG_ASSERT(mysql == NULL);
 


Attachment: [text/bzr-bundle] bzr/dlenev@mysql.com-20100915210440-q1bxry3qmyrb8878.bundle
Thread
bzr commit into mysql-5.5-runtime branch (dlenev:3139)Dmitry Lenev15 Sep