List:Commits« Previous MessageNext Message »
From:Marc Alff Date:March 7 2010 6:54pm
Subject:bzr commit into mysql-6.0-codebase-bugfixing branch (marc.alff:3796)
View as plain text  
#At file:///home/malff/BZR_TREE/mysql-6.0-codebase-bugfixing/ based on revid:bjorn.munch@stripped

 3796 Marc Alff	2010-03-07 [merge]
      Manual merge mysql-next-mr-bugfixing (revno 3124) --> mysql-6.0-codebase-bugfixing

    added:
      mysql-test/suite/perfschema/r/pfs_upgrade.result
      mysql-test/suite/perfschema/t/pfs_upgrade.test
    modified:
      include/mysql/psi/mysql_thread.h
      mysql-test/suite/perfschema/r/binlog_mix.result
      mysql-test/suite/perfschema/r/binlog_row.result
      mysql-test/suite/perfschema/r/dml_setup_instruments.result
      scripts/mysql_system_tables.sql
      sql/mdl.cc
      sql/mdl.h
      storage/perfschema/pfs_instr.cc
      storage/perfschema/unittest/pfs-t.cc
=== modified file 'include/mysql/psi/mysql_thread.h'
--- a/include/mysql/psi/mysql_thread.h	2009-12-01 01:33:55 +0000
+++ b/include/mysql/psi/mysql_thread.h	2010-03-07 18:54:05 +0000
@@ -107,6 +107,22 @@ struct st_mysql_rwlock
 };
 
 /**
+  An instrumented prlock structure.
+  @sa mysql_prlock_t
+*/
+struct st_mysql_prlock
+{
+  /** The real prlock */
+  rw_pr_lock_t m_prlock;
+  /**
+    The instrumentation hook.
+    Note that this hook is not conditionally defined,
+    for binary compatibility of the @c mysql_rwlock_t interface.
+  */
+  struct PSI_rwlock *m_psi;
+};
+
+/**
   Type of an instrumented rwlock.
   @c mysql_rwlock_t is a drop-in replacement for @c pthread_rwlock_t.
   @sa mysql_rwlock_init
@@ -120,6 +136,20 @@ struct st_mysql_rwlock
 typedef struct st_mysql_rwlock mysql_rwlock_t;
 
 /**
+  Type of an instrumented prlock.
+  A prlock is a read write lock that 'prefers readers' (pr).
+  @c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t.
+  @sa mysql_prlock_init
+  @sa mysql_prlock_rdlock
+  @sa mysql_prlock_tryrdlock
+  @sa mysql_prlock_wrlock
+  @sa mysql_prlock_trywrlock
+  @sa mysql_prlock_unlock
+  @sa mysql_prlock_destroy
+*/
+typedef struct st_mysql_prlock mysql_prlock_t;
+
+/**
   An instrumented cond structure.
   @sa mysql_cond_t
 */
@@ -312,6 +342,19 @@ typedef struct st_mysql_cond mysql_cond_
 #endif
 
 /**
+  @def mysql_prlock_init(K, RW)
+  Instrumented rw_pr_init.
+  @c mysql_prlock_init is a replacement for @c rw_pr_init.
+  @param K The PSI_rwlock_key for this instrumented prlock
+  @param RW The prlock to initialize
+*/
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(K, RW)
+#else
+  #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(RW)
+#endif
+
+/**
   @def mysql_rwlock_destroy(RW)
   Instrumented rwlock_destroy.
   @c mysql_rwlock_destroy is a drop-in replacement
@@ -320,6 +363,14 @@ typedef struct st_mysql_cond mysql_cond_
 #define mysql_rwlock_destroy(RW) inline_mysql_rwlock_destroy(RW)
 
 /**
+  @def mysql_prlock_destroy(RW)
+  Instrumented rw_pr_destroy.
+  @c mysql_prlock_destroy is a drop-in replacement
+  for @c rw_pr_destroy.
+*/
+#define mysql_prlock_destroy(RW) inline_mysql_prlock_destroy(RW)
+
+/**
   @def mysql_rwlock_rdlock(RW)
   Instrumented rwlock_rdlock.
   @c mysql_rwlock_rdlock is a drop-in replacement
@@ -334,6 +385,20 @@ typedef struct st_mysql_cond mysql_cond_
 #endif
 
 /**
+  @def mysql_prlock_rdlock(RW)
+  Instrumented rw_pr_rdlock.
+  @c mysql_prlock_rdlock is a drop-in replacement
+  for @c rw_pr_rdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_prlock_rdlock(RW) \
+    inline_mysql_prlock_rdlock(RW, __FILE__, __LINE__)
+#else
+  #define mysql_prlock_rdlock(RW) \
+    inline_mysql_prlock_rdlock(RW)
+#endif
+
+/**
   @def mysql_rwlock_wrlock(RW)
   Instrumented rwlock_wrlock.
   @c mysql_rwlock_wrlock is a drop-in replacement
@@ -348,6 +413,20 @@ typedef struct st_mysql_cond mysql_cond_
 #endif
 
 /**
+  @def mysql_prlock_wrlock(RW)
+  Instrumented rw_pr_wrlock.
+  @c mysql_prlock_wrlock is a drop-in replacement
+  for @c rw_pr_wrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_prlock_wrlock(RW) \
+    inline_mysql_prlock_wrlock(RW, __FILE__, __LINE__)
+#else
+  #define mysql_prlock_wrlock(RW) \
+    inline_mysql_prlock_wrlock(RW)
+#endif
+
+/**
   @def mysql_rwlock_tryrdlock(RW)
   Instrumented rwlock_tryrdlock.
   @c mysql_rwlock_tryrdlock is a drop-in replacement
@@ -362,6 +441,20 @@ typedef struct st_mysql_cond mysql_cond_
 #endif
 
 /**
+  @def mysql_prlock_tryrdlock(RW)
+  Instrumented rw_pr_tryrdlock.
+  @c mysql_prlock_tryrdlock is a drop-in replacement
+  for @c rw_pr_tryrdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_prlock_tryrdlock(RW) \
+    inline_mysql_prlock_tryrdlock(RW, __FILE__, __LINE__)
+#else
+  #define mysql_prlock_tryrdlock(RW) \
+    inline_mysql_prlock_tryrdlock(RW)
+#endif
+
+/**
   @def mysql_rwlock_trywrlock(RW)
   Instrumented rwlock_trywrlock.
   @c mysql_rwlock_trywrlock is a drop-in replacement
@@ -376,6 +469,20 @@ typedef struct st_mysql_cond mysql_cond_
 #endif
 
 /**
+  @def mysql_prlock_trywrlock(RW)
+  Instrumented rw_pr_trywrlock.
+  @c mysql_prlock_trywrlock is a drop-in replacement
+  for @c rw_pr_trywrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_prlock_trywrlock(RW) \
+    inline_mysql_prlock_trywrlock(RW, __FILE__, __LINE__)
+#else
+  #define mysql_prlock_trywrlock(RW) \
+    inline_mysql_prlock_trywrlock(RW)
+#endif
+
+/**
   @def mysql_rwlock_unlock(RW)
   Instrumented rwlock_unlock.
   @c mysql_rwlock_unlock is a drop-in replacement
@@ -384,8 +491,16 @@ typedef struct st_mysql_cond mysql_cond_
 #define mysql_rwlock_unlock(RW) inline_mysql_rwlock_unlock(RW)
 
 /**
+  @def mysql_prlock_unlock(RW)
+  Instrumented rw_pr_unlock.
+  @c mysql_prlock_unlock is a drop-in replacement
+  for @c rw_pr_unlock.
+*/
+#define mysql_prlock_unlock(RW) inline_mysql_prlock_unlock(RW)
+
+/**
   @def mysql_cond_init(K, C, A)
-  Instrumented rwlock_init.
+  Instrumented cond_init.
   @c mysql_cond_init is a replacement for @c pthread_cond_init.
   @param C The cond to initialize
   @param K The PSI_cond_key for this instrumented cond
@@ -633,6 +748,21 @@ static inline int inline_mysql_rwlock_in
   return my_rwlock_init(&that->m_rwlock, NULL);
 }
 
+static inline int inline_mysql_prlock_init(
+#ifdef HAVE_PSI_INTERFACE
+  PSI_rwlock_key key,
+#endif
+  mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+  that->m_psi= (PSI_server ? PSI_server->init_rwlock(key, &that->m_prlock)
+                           : NULL);
+#else
+  that->m_psi= NULL;
+#endif
+  return rw_pr_init(&that->m_prlock);
+}
+
 static inline int inline_mysql_rwlock_destroy(
   mysql_rwlock_t *that)
 {
@@ -646,6 +776,19 @@ static inline int inline_mysql_rwlock_de
   return rwlock_destroy(&that->m_rwlock);
 }
 
+static inline int inline_mysql_prlock_destroy(
+  mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+  if (likely(PSI_server && that->m_psi))
+  {
+    PSI_server->destroy_rwlock(that->m_psi);
+    that->m_psi= NULL;
+  }
+#endif
+  return rw_pr_destroy(&that->m_prlock);
+}
+
 static inline int inline_mysql_rwlock_rdlock(
   mysql_rwlock_t *that
 #ifdef HAVE_PSI_INTERFACE
@@ -672,6 +815,32 @@ static inline int inline_mysql_rwlock_rd
   return result;
 }
 
+static inline int inline_mysql_prlock_rdlock(
+  mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+  , const char *src_file, uint src_line
+#endif
+  )
+{
+  int result;
+#ifdef HAVE_PSI_INTERFACE
+  struct PSI_rwlock_locker *locker= NULL;
+  if (likely(PSI_server && that->m_psi))
+  {
+    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+                                                 PSI_RWLOCK_READLOCK);
+    if (likely(locker != NULL))
+      PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+  }
+#endif
+  result= rw_pr_rdlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+  if (likely(locker != NULL))
+    PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+  return result;
+}
+
 static inline int inline_mysql_rwlock_wrlock(
   mysql_rwlock_t *that
 #ifdef HAVE_PSI_INTERFACE
@@ -698,6 +867,32 @@ static inline int inline_mysql_rwlock_wr
   return result;
 }
 
+static inline int inline_mysql_prlock_wrlock(
+  mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+  , const char *src_file, uint src_line
+#endif
+  )
+{
+  int result;
+#ifdef HAVE_PSI_INTERFACE
+  struct PSI_rwlock_locker *locker= NULL;
+  if (likely(PSI_server && that->m_psi))
+  {
+    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+                                                 PSI_RWLOCK_WRITELOCK);
+    if (likely(locker != NULL))
+      PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+  }
+#endif
+  result= rw_pr_wrlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+  if (likely(locker != NULL))
+    PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+  return result;
+}
+
 static inline int inline_mysql_rwlock_tryrdlock(
   mysql_rwlock_t *that
 #ifdef HAVE_PSI_INTERFACE
@@ -724,6 +919,32 @@ static inline int inline_mysql_rwlock_tr
   return result;
 }
 
+static inline int inline_mysql_prlock_tryrdlock(
+  mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+  , const char *src_file, uint src_line
+#endif
+  )
+{
+  int result;
+#ifdef HAVE_PSI_INTERFACE
+  struct PSI_rwlock_locker *locker= NULL;
+  if (likely(PSI_server && that->m_psi))
+  {
+    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+                                                 PSI_RWLOCK_TRYREADLOCK);
+    if (likely(locker != NULL))
+      PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+  }
+#endif
+  result= rw_pr_tryrdlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+  if (likely(locker != NULL))
+    PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+  return result;
+}
+
 static inline int inline_mysql_rwlock_trywrlock(
   mysql_rwlock_t *that
 #ifdef HAVE_PSI_INTERFACE
@@ -750,6 +971,32 @@ static inline int inline_mysql_rwlock_tr
   return result;
 }
 
+static inline int inline_mysql_prlock_trywrlock(
+  mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+  , const char *src_file, uint src_line
+#endif
+  )
+{
+  int result;
+#ifdef HAVE_PSI_INTERFACE
+  struct PSI_rwlock_locker *locker= NULL;
+  if (likely(PSI_server && that->m_psi))
+  {
+    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+                                                 PSI_RWLOCK_TRYWRITELOCK);
+    if (likely(locker != NULL))
+      PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+  }
+#endif
+  result= rw_pr_trywrlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+  if (likely(locker != NULL))
+    PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+  return result;
+}
+
 static inline int inline_mysql_rwlock_unlock(
   mysql_rwlock_t *that)
 {
@@ -767,6 +1014,23 @@ static inline int inline_mysql_rwlock_un
   return result;
 }
 
+static inline int inline_mysql_prlock_unlock(
+  mysql_prlock_t *that)
+{
+  int result;
+#ifdef HAVE_PSI_INTERFACE
+  struct PSI_thread *thread;
+  if (likely(PSI_server && that->m_psi))
+  {
+    thread= PSI_server->get_thread();
+    if (likely(thread != NULL))
+      PSI_server->unlock_rwlock(thread, that->m_psi);
+  }
+#endif
+  result= rw_pr_unlock(&that->m_prlock);
+  return result;
+}
+
 static inline int inline_mysql_cond_init(
 #ifdef HAVE_PSI_INTERFACE
   PSI_cond_key key,

=== modified file 'mysql-test/suite/perfschema/r/binlog_mix.result'
--- a/mysql-test/suite/perfschema/r/binlog_mix.result	2010-01-12 01:48:52 +0000
+++ b/mysql-test/suite/perfschema/r/binlog_mix.result	2010-03-07 18:54:05 +0000
@@ -35,6 +35,8 @@ master-bin.000001	#	Update_rows	#	#	tabl
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	#	#	COMMIT
 master-bin.000001	#	Query	#	#	use `test`; drop table if exists test.t1
@@ -56,6 +58,8 @@ master-bin.000001	#	Table_map	#	#	table_
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #

=== modified file 'mysql-test/suite/perfschema/r/binlog_row.result'
--- a/mysql-test/suite/perfschema/r/binlog_row.result	2010-01-12 01:48:52 +0000
+++ b/mysql-test/suite/perfschema/r/binlog_row.result	2010-03-07 18:54:05 +0000
@@ -35,6 +35,8 @@ master-bin.000001	#	Update_rows	#	#	tabl
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	#	#	COMMIT
 master-bin.000001	#	Query	#	#	use `test`; drop table if exists test.t1
@@ -56,6 +58,8 @@ master-bin.000001	#	Table_map	#	#	table_
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #
 master-bin.000001	#	Update_rows	#	#	table_id: #

=== modified file 'mysql-test/suite/perfschema/r/dml_setup_instruments.result'
--- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result	2010-02-17 21:07:50 +0000
+++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result	2010-03-07 18:54:05 +0000
@@ -25,9 +25,10 @@ wait/synch/rwlock/sql/LOCK_system_variab
 wait/synch/rwlock/sql/LOCK_sys_init_connect	YES	YES
 wait/synch/rwlock/sql/LOCK_sys_init_slave	YES	YES
 wait/synch/rwlock/sql/LOGGER::LOCK_logger	YES	YES
+wait/synch/rwlock/sql/MDL_context::waiting_for_lock	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
-wait/synch/rwlock/sql/THR_LOCK_udf	YES	YES
 select * from performance_schema.SETUP_INSTRUMENTS
 where name like 'Wait/Synch/Cond/sql/%'
   and name not in (

=== added file 'mysql-test/suite/perfschema/r/pfs_upgrade.result'
--- a/mysql-test/suite/perfschema/r/pfs_upgrade.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/perfschema/r/pfs_upgrade.result	2010-03-07 18:54:05 +0000
@@ -0,0 +1,153 @@
+drop table if exists test.user_table;
+drop procedure if exists test.user_proc;
+drop function if exists test.user_func;
+drop event if exists test.user_event;
+"Testing mysql_upgrade with TABLE performance_schema.user_table"
+create table test.user_table(a int);
+use performance_schema;
+show tables like "user_table";
+Tables_in_performance_schema (user_table)
+user_table
+ERROR 1644 (HY000) at line 180: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 205: Table 'COND_INSTANCES' already exists
+ERROR 1050 (42S01) at line 235: Table 'EVENTS_WAITS_CURRENT' already exists
+ERROR 1050 (42S01) at line 249: Table 'EVENTS_WAITS_HISTORY' already exists
+ERROR 1050 (42S01) at line 263: Table 'EVENTS_WAITS_HISTORY_LONG' already exists
+ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 304: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 325: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 342: Table 'FILE_INSTANCES' already exists
+ERROR 1050 (42S01) at line 361: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 381: Table 'FILE_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 398: Table 'MUTEX_INSTANCES' already exists
+ERROR 1050 (42S01) at line 416: Table 'PERFORMANCE_TIMERS' already exists
+ERROR 1050 (42S01) at line 433: Table 'PROCESSLIST' already exists
+ERROR 1050 (42S01) at line 451: Table 'RWLOCK_INSTANCES' already exists
+ERROR 1050 (42S01) at line 467: Table 'SETUP_CONSUMERS' already exists
+ERROR 1050 (42S01) at line 484: Table 'SETUP_INSTRUMENTS' already exists
+ERROR 1050 (42S01) at line 504: Table 'SETUP_OBJECTS' already exists
+ERROR 1050 (42S01) at line 520: Table 'SETUP_TIMERS' already exists
+FATAL ERROR: Upgrade failed
+show tables like "user_table";
+Tables_in_performance_schema (user_table)
+user_table
+use test;
+drop table test.user_table;
+"Testing mysql_upgrade with VIEW performance_schema.user_view"
+create view test.user_view as select "Not supposed to be here";
+use performance_schema;
+show tables like "user_view";
+Tables_in_performance_schema (user_view)
+user_view
+ERROR 1644 (HY000) at line 180: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 205: Table 'COND_INSTANCES' already exists
+ERROR 1050 (42S01) at line 235: Table 'EVENTS_WAITS_CURRENT' already exists
+ERROR 1050 (42S01) at line 249: Table 'EVENTS_WAITS_HISTORY' already exists
+ERROR 1050 (42S01) at line 263: Table 'EVENTS_WAITS_HISTORY_LONG' already exists
+ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 304: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 325: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 342: Table 'FILE_INSTANCES' already exists
+ERROR 1050 (42S01) at line 361: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 381: Table 'FILE_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 398: Table 'MUTEX_INSTANCES' already exists
+ERROR 1050 (42S01) at line 416: Table 'PERFORMANCE_TIMERS' already exists
+ERROR 1050 (42S01) at line 433: Table 'PROCESSLIST' already exists
+ERROR 1050 (42S01) at line 451: Table 'RWLOCK_INSTANCES' already exists
+ERROR 1050 (42S01) at line 467: Table 'SETUP_CONSUMERS' already exists
+ERROR 1050 (42S01) at line 484: Table 'SETUP_INSTRUMENTS' already exists
+ERROR 1050 (42S01) at line 504: Table 'SETUP_OBJECTS' already exists
+ERROR 1050 (42S01) at line 520: Table 'SETUP_TIMERS' already exists
+FATAL ERROR: Upgrade failed
+show tables like "user_view";
+Tables_in_performance_schema (user_view)
+user_view
+use test;
+drop view test.user_view;
+"Testing mysql_upgrade with PROCEDURE performance_schema.user_proc"
+create procedure test.user_proc()
+select "Not supposed to be here";
+update mysql.proc set db='performance_schema' where name='user_proc';
+ERROR 1644 (HY000) at line 180: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 205: Table 'COND_INSTANCES' already exists
+ERROR 1050 (42S01) at line 235: Table 'EVENTS_WAITS_CURRENT' already exists
+ERROR 1050 (42S01) at line 249: Table 'EVENTS_WAITS_HISTORY' already exists
+ERROR 1050 (42S01) at line 263: Table 'EVENTS_WAITS_HISTORY_LONG' already exists
+ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 304: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 325: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 342: Table 'FILE_INSTANCES' already exists
+ERROR 1050 (42S01) at line 361: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 381: Table 'FILE_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 398: Table 'MUTEX_INSTANCES' already exists
+ERROR 1050 (42S01) at line 416: Table 'PERFORMANCE_TIMERS' already exists
+ERROR 1050 (42S01) at line 433: Table 'PROCESSLIST' already exists
+ERROR 1050 (42S01) at line 451: Table 'RWLOCK_INSTANCES' already exists
+ERROR 1050 (42S01) at line 467: Table 'SETUP_CONSUMERS' already exists
+ERROR 1050 (42S01) at line 484: Table 'SETUP_INSTRUMENTS' already exists
+ERROR 1050 (42S01) at line 504: Table 'SETUP_OBJECTS' already exists
+ERROR 1050 (42S01) at line 520: Table 'SETUP_TIMERS' already exists
+FATAL ERROR: Upgrade failed
+select name from mysql.proc where db='performance_schema';
+name
+user_proc
+update mysql.proc set db='test' where name='user_proc';
+drop procedure test.user_proc;
+"Testing mysql_upgrade with FUNCTION performance_schema.user_func"
+create function test.user_func() returns integer
+return 0;
+update mysql.proc set db='performance_schema' where name='user_func';
+ERROR 1644 (HY000) at line 180: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 205: Table 'COND_INSTANCES' already exists
+ERROR 1050 (42S01) at line 235: Table 'EVENTS_WAITS_CURRENT' already exists
+ERROR 1050 (42S01) at line 249: Table 'EVENTS_WAITS_HISTORY' already exists
+ERROR 1050 (42S01) at line 263: Table 'EVENTS_WAITS_HISTORY_LONG' already exists
+ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 304: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 325: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 342: Table 'FILE_INSTANCES' already exists
+ERROR 1050 (42S01) at line 361: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 381: Table 'FILE_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 398: Table 'MUTEX_INSTANCES' already exists
+ERROR 1050 (42S01) at line 416: Table 'PERFORMANCE_TIMERS' already exists
+ERROR 1050 (42S01) at line 433: Table 'PROCESSLIST' already exists
+ERROR 1050 (42S01) at line 451: Table 'RWLOCK_INSTANCES' already exists
+ERROR 1050 (42S01) at line 467: Table 'SETUP_CONSUMERS' already exists
+ERROR 1050 (42S01) at line 484: Table 'SETUP_INSTRUMENTS' already exists
+ERROR 1050 (42S01) at line 504: Table 'SETUP_OBJECTS' already exists
+ERROR 1050 (42S01) at line 520: Table 'SETUP_TIMERS' already exists
+FATAL ERROR: Upgrade failed
+select name from mysql.proc where db='performance_schema';
+name
+user_func
+update mysql.proc set db='test' where name='user_func';
+drop function test.user_func;
+"Testing mysql_upgrade with EVENT performance_schema.user_event"
+create event test.user_event on schedule every 1 day do
+select "not supposed to be here";
+update mysql.event set db='performance_schema' where name='user_event';
+ERROR 1644 (HY000) at line 180: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 205: Table 'COND_INSTANCES' already exists
+ERROR 1050 (42S01) at line 235: Table 'EVENTS_WAITS_CURRENT' already exists
+ERROR 1050 (42S01) at line 249: Table 'EVENTS_WAITS_HISTORY' already exists
+ERROR 1050 (42S01) at line 263: Table 'EVENTS_WAITS_HISTORY_LONG' already exists
+ERROR 1050 (42S01) at line 283: Table 'EVENTS_WAITS_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 304: Table 'EVENTS_WAITS_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 325: Table 'EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 342: Table 'FILE_INSTANCES' already exists
+ERROR 1050 (42S01) at line 361: Table 'FILE_SUMMARY_BY_EVENT_NAME' already exists
+ERROR 1050 (42S01) at line 381: Table 'FILE_SUMMARY_BY_INSTANCE' already exists
+ERROR 1050 (42S01) at line 398: Table 'MUTEX_INSTANCES' already exists
+ERROR 1050 (42S01) at line 416: Table 'PERFORMANCE_TIMERS' already exists
+ERROR 1050 (42S01) at line 433: Table 'PROCESSLIST' already exists
+ERROR 1050 (42S01) at line 451: Table 'RWLOCK_INSTANCES' already exists
+ERROR 1050 (42S01) at line 467: Table 'SETUP_CONSUMERS' already exists
+ERROR 1050 (42S01) at line 484: Table 'SETUP_INSTRUMENTS' already exists
+ERROR 1050 (42S01) at line 504: Table 'SETUP_OBJECTS' already exists
+ERROR 1050 (42S01) at line 520: Table 'SETUP_TIMERS' already exists
+FATAL ERROR: Upgrade failed
+select name from mysql.event where db='performance_schema';
+name
+user_event
+update mysql.event set db='test' where name='user_event';
+drop event test.user_event;

=== added file 'mysql-test/suite/perfschema/t/pfs_upgrade.test'
--- a/mysql-test/suite/perfschema/t/pfs_upgrade.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/perfschema/t/pfs_upgrade.test	2010-03-07 18:54:05 +0000
@@ -0,0 +1,137 @@
+# Copyright (C) 2010 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Tests for PERFORMANCE_SCHEMA
+# Make sure mysql_upgrade does not destroy data in a 'performance_schema'
+# database.
+# 
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+
+--disable_warnings
+drop table if exists test.user_table;
+drop procedure if exists test.user_proc;
+drop function if exists test.user_func;
+drop event if exists test.user_event;
+--enable_warnings
+
+--echo "Testing mysql_upgrade with TABLE performance_schema.user_table"
+
+create table test.user_table(a int);
+
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--copy_file $MYSQLD_DATADIR/test/user_table.frm $MYSQLD_DATADIR/performance_schema/user_table.frm
+
+# Make sure the table is visible
+use performance_schema;
+show tables like "user_table";
+
+--error 1
+--exec $MYSQL_UPGRADE --skip-verbose > $MYSQLTEST_VARDIR/tmp/pfs_upgrade.out 2> $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+# Verify that mysql_upgrade complained about the performance_schema
+--cat_file $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+# Make sure the table is still visible
+show tables like "user_table";
+
+use test;
+
+--remove_file $MYSQLD_DATADIR/performance_schema/user_table.frm
+drop table test.user_table;
+
+--echo "Testing mysql_upgrade with VIEW performance_schema.user_view"
+
+create view test.user_view as select "Not supposed to be here";
+
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--copy_file $MYSQLD_DATADIR/test/user_view.frm $MYSQLD_DATADIR/performance_schema/user_view.frm
+
+# Make sure the view is visible
+use performance_schema;
+show tables like "user_view";
+
+--error 1
+--exec $MYSQL_UPGRADE --skip-verbose > $MYSQLTEST_VARDIR/tmp/pfs_upgrade.out 2> $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+# Verify that mysql_upgrade complained about the performance_schema
+--cat_file $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+# Make sure the view is still visible
+show tables like "user_view";
+
+use test;
+
+--remove_file $MYSQLD_DATADIR/performance_schema/user_view.frm
+drop view test.user_view;
+
+--echo "Testing mysql_upgrade with PROCEDURE performance_schema.user_proc"
+
+create procedure test.user_proc()
+  select "Not supposed to be here";
+
+update mysql.proc set db='performance_schema' where name='user_proc';
+
+--error 1
+--exec $MYSQL_UPGRADE --skip-verbose > $MYSQLTEST_VARDIR/tmp/pfs_upgrade.out 2> $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+# Verify that mysql_upgrade complained about the performance_schema
+--cat_file $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+select name from mysql.proc where db='performance_schema';
+
+update mysql.proc set db='test' where name='user_proc';
+drop procedure test.user_proc;
+
+--echo "Testing mysql_upgrade with FUNCTION performance_schema.user_func"
+
+create function test.user_func() returns integer
+  return 0;
+
+update mysql.proc set db='performance_schema' where name='user_func';
+
+--error 1
+--exec $MYSQL_UPGRADE --skip-verbose > $MYSQLTEST_VARDIR/tmp/pfs_upgrade.out 2> $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+# Verify that mysql_upgrade complained about the performance_schema
+--cat_file $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+select name from mysql.proc where db='performance_schema';
+
+update mysql.proc set db='test' where name='user_func';
+drop function test.user_func;
+
+--echo "Testing mysql_upgrade with EVENT performance_schema.user_event"
+
+create event test.user_event on schedule every 1 day do
+  select "not supposed to be here";
+
+update mysql.event set db='performance_schema' where name='user_event';
+
+--error 1
+--exec $MYSQL_UPGRADE --skip-verbose > $MYSQLTEST_VARDIR/tmp/pfs_upgrade.out 2> $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+# Verify that mysql_upgrade complained about the performance_schema
+--cat_file $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+
+select name from mysql.event where db='performance_schema';
+
+update mysql.event set db='test' where name='user_event';
+drop event test.user_event;
+
+--remove_file $MYSQLTEST_VARDIR/tmp/pfs_upgrade.out
+--remove_file $MYSQLTEST_VARDIR/tmp/pfs_upgrade.err
+

=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql	2010-02-02 13:48:37 +0000
+++ b/scripts/mysql_system_tables.sql	2010-03-07 18:54:05 +0000
@@ -1,4 +1,4 @@
--- Copyright (C) 2008-2009 Sun Microsystems, Inc
+-- Copyright (C) 2008, 2010 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
@@ -102,18 +102,92 @@ CREATE TABLE IF NOT EXISTS event ( db ch
 #
 DROP TABLE IF EXISTS mysql.online_backup;
 
+--
+-- PERFORMANCE SCHEMA INSTALLATION
+-- Note that this script is also reused by mysql_upgrade,
+-- so we have to be very careful here to not destroy any
+-- existing database named 'performance_schema' if it
+-- can contain user data.
+-- In case of downgrade, it's ok to drop unknown tables
+-- from a future version, as long as they belong to the
+-- performance schema engine.
+--
+
+set @have_old_pfs= (select count(*) from information_schema.schemata where schema_name='performance_schema');
+
+SET @l1="SET @broken_tables = (select count(*) from information_schema.tables";
+SET @l2=" where engine != \'PERFORMANCE_SCHEMA\' and table_schema=\'performance_schema\')";
+SET @cmd=concat(@l1,@l2);
+
+-- Work around for bug#49542
+SET @str = IF(@have_old_pfs = 1, @cmd, 'SET @broken_tables = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+SET @l1="SET @broken_views = (select count(*) from information_schema.views";
+SET @l2=" where table_schema='performance_schema')";
+SET @cmd=concat(@l1,@l2);
+
+-- Work around for bug#49542
+SET @str = IF(@have_old_pfs = 1, @cmd, 'SET @broken_views = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+SET @broken_routines = (select count(*) from mysql.proc where db='performance_schema');
+
+SET @broken_events = (select count(*) from mysql.event where db='performance_schema');
+
+SET @broken_pfs= (select @broken_tables + @broken_views + @broken_routines + @broken_events);
 
 --
 -- The performance schema database.
--- This database is always created, even in --without-perfschema builds,
+-- Only drop and create the database if this is safe (no broken_pfs).
+-- This database is created, even in --without-perfschema builds,
 -- so that the database name is always reserved by the MySQL implementation.
 --
 
-set @have_pfs= (select count(engine) from information_schema.engines where engine='PERFORMANCE_SCHEMA' and support != 'NO');
+SET @cmd= "DROP DATABASE IF EXISTS performance_schema";
+
+SET @str = IF(@broken_pfs = 0, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+SET @cmd= "CREATE DATABASE performance_schema character set utf8";
 
-DROP DATABASE IF EXISTS performance_schema;
+SET @str = IF(@broken_pfs = 0, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- Unlike 'performance_schema', the 'mysql' database is reserved already,
+-- so no user procedure is supposed to be there
+--
+drop procedure if exists mysql.die;
+create procedure mysql.die() signal sqlstate 'HY000' set message_text='Unexpected content found in the performance_schema database.';
+
+--
+-- For broken upgrades, SIGNAL the error
+--
+
+SET @cmd="call mysql.die()";
 
-CREATE DATABASE performance_schema character set utf8;
+SET @str = IF(@broken_pfs > 0, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+drop procedure mysql.die;
+
+--
+-- From this point, only create the performance schema tables
+-- if the server is build with performance schema
+--
+
+set @have_pfs= (select count(engine) from information_schema.engines where engine='PERFORMANCE_SCHEMA' and support != 'NO');
 
 --
 -- TABLE COND_INSTANCES

=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2010-03-01 18:08:17 +0000
+++ b/sql/mdl.cc	2010-03-07 18:54:05 +0000
@@ -19,6 +19,54 @@
 #include <hash.h>
 #include <mysqld_error.h>
 
+#ifdef HAVE_PSI_INTERFACE
+static PSI_mutex_key key_MDL_map_mutex;
+static PSI_mutex_key key_MDL_context_signal_mutex;
+
+static PSI_mutex_info all_mdl_mutexes[]=
+{
+  { &key_MDL_map_mutex, "MDL_map::mutex", PSI_FLAG_GLOBAL},
+  { &key_MDL_context_signal_mutex, "MDL_context::signal", 0}
+};
+
+static PSI_rwlock_key key_MDL_lock_rwlock;
+static PSI_rwlock_key key_MDL_context_waiting_for_rwlock;
+
+static PSI_rwlock_info all_mdl_rwlocks[]=
+{
+  { &key_MDL_lock_rwlock, "MDL_lock::rwlock", 0},
+  { &key_MDL_context_waiting_for_rwlock, "MDL_context::waiting_for_lock", 0}
+};
+
+static PSI_cond_key key_MDL_context_signal_cond;
+
+static PSI_cond_info all_mdl_conds[]=
+{
+  { &key_MDL_context_signal_cond, "MDL_context::signal", 0}
+};
+
+/**
+  Initialise all the performance schema instrumentation points
+  used by the MDL subsystem.
+*/
+static void init_mdl_psi_keys(void)
+{
+  const char *category= "sql";
+  int count;
+
+  if (PSI_server == NULL)
+    return;
+
+  count= array_elements(all_mdl_mutexes);
+  PSI_server->register_mutex(category, all_mdl_mutexes, count);
+
+  count= array_elements(all_mdl_rwlocks);
+  PSI_server->register_rwlock(category, all_mdl_rwlocks, count);
+
+  count= array_elements(all_mdl_conds);
+  PSI_server->register_cond(category, all_mdl_conds, count);
+}
+#endif /* HAVE_PSI_INTERFACE */
 
 void notify_shared_lock(THD *thd, MDL_ticket *conflicting_ticket);
 
@@ -178,7 +226,7 @@ public:
           If m_wrlock prefers readers (actually ignoring pending writers is
           enough) ctxA and ctxB will continue and no deadlock will occur.
   */
-  rw_pr_lock_t m_rwlock;
+  mysql_prlock_t m_rwlock;
 
   bool is_empty() const
   {
@@ -240,12 +288,12 @@ public:
     m_ref_release(0),
     m_is_destroyed(FALSE)
   {
-    rw_pr_init(&m_rwlock);
+    mysql_prlock_init(key_MDL_lock_rwlock, &m_rwlock);
   }
 
   virtual ~MDL_lock()
   {
-    rw_pr_destroy(&m_rwlock);
+    mysql_prlock_destroy(&m_rwlock);
   }
   inline static void destroy(MDL_lock *lock);
 public:
@@ -368,6 +416,11 @@ void mdl_init()
 {
   DBUG_ASSERT(! mdl_initialized);
   mdl_initialized= TRUE;
+
+#ifdef HAVE_PSI_INTERFACE
+  init_mdl_psi_keys();
+#endif
+
   mdl_locks.init();
 }
 
@@ -393,7 +446,7 @@ void mdl_destroy()
 
 void MDL_map::init()
 {
-  mysql_mutex_init(NULL /* pfs key */,&m_mutex, NULL);
+  mysql_mutex_init(key_MDL_map_mutex, &m_mutex, NULL);
   my_hash_init(&m_locks, &my_charset_bin, 16 /* FIXME */, 0, 0,
                mdl_locks_key, 0, 0);
 }
@@ -507,7 +560,7 @@ bool MDL_map::move_from_hash_to_lock_mut
   lock->m_ref_usage++;
   mysql_mutex_unlock(&m_mutex);
 
-  rw_pr_wrlock(&lock->m_rwlock);
+  mysql_prlock_wrlock(&lock->m_rwlock);
   lock->m_ref_release++;
   if (unlikely(lock->m_is_destroyed))
   {
@@ -522,7 +575,7 @@ bool MDL_map::move_from_hash_to_lock_mut
     */
     uint ref_usage= lock->m_ref_usage;
     uint ref_release= lock->m_ref_release;
-    rw_pr_unlock(&lock->m_rwlock);
+    mysql_prlock_unlock(&lock->m_rwlock);
     if (ref_usage == ref_release)
       MDL_lock::destroy(lock);
     return TRUE;
@@ -565,7 +618,7 @@ void MDL_map::remove(MDL_lock *lock)
   lock->m_is_destroyed= TRUE;
   ref_usage= lock->m_ref_usage;
   ref_release= lock->m_ref_release;
-  rw_pr_unlock(&lock->m_rwlock);
+  mysql_prlock_unlock(&lock->m_rwlock);
   mysql_mutex_unlock(&m_mutex);
   if (ref_usage == ref_release)
     MDL_lock::destroy(lock);
@@ -586,9 +639,9 @@ MDL_context::MDL_context()
   m_deadlock_weight(0),
   m_signal(NO_WAKE_UP)
 {
-  rw_pr_init(&m_waiting_for_lock);
-  mysql_mutex_init(NULL /* pfs key */, &m_signal_lock, NULL);
-  mysql_cond_init(NULL /* pfs key */, &m_signal_cond, NULL);
+  mysql_prlock_init(key_MDL_context_waiting_for_rwlock, &m_waiting_for_lock);
+  mysql_mutex_init(key_MDL_context_signal_mutex, &m_signal_lock, NULL);
+  mysql_cond_init(key_MDL_context_signal_mutex, &m_signal_cond, NULL);
 }
 
 
@@ -608,7 +661,7 @@ void MDL_context::destroy()
 {
   DBUG_ASSERT(m_tickets.is_empty());
 
-  rw_pr_destroy(&m_waiting_for_lock);
+  mysql_prlock_destroy(&m_waiting_for_lock);
   mysql_mutex_destroy(&m_signal_lock);
   mysql_cond_destroy(&m_signal_cond);
 }
@@ -1103,7 +1156,7 @@ MDL_lock::can_grant_lock(enum_mdl_type t
 
 void MDL_lock::remove_ticket(Ticket_list MDL_lock::*list, MDL_ticket *ticket)
 {
-  rw_pr_wrlock(&m_rwlock);
+  mysql_prlock_wrlock(&m_rwlock);
   (this->*list).remove_ticket(ticket);
   if (is_empty())
     mdl_locks.remove(this);
@@ -1114,7 +1167,7 @@ void MDL_lock::remove_ticket(Ticket_list
       which now might be able to do it. Wake them up!
     */
     wake_up_waiters();
-    rw_pr_unlock(&m_rwlock);
+    mysql_prlock_unlock(&m_rwlock);
   }
 }
 
@@ -1134,9 +1187,9 @@ bool MDL_lock::has_pending_conflicting_l
 
   mysql_mutex_assert_not_owner(&LOCK_open);
 
-  rw_pr_rdlock(&m_rwlock);
+  mysql_prlock_rdlock(&m_rwlock);
   result= (m_waiting.bitmap() & incompatible_granted_types_bitmap()[type]);
-  rw_pr_unlock(&m_rwlock);
+  mysql_prlock_unlock(&m_rwlock);
   return result;
 }
 
@@ -1330,7 +1383,7 @@ MDL_context::try_acquire_lock(MDL_reques
   {
     ticket->m_lock= lock;
     lock->m_granted.add_ticket(ticket);
-    rw_pr_unlock(&lock->m_rwlock);
+    mysql_prlock_unlock(&lock->m_rwlock);
 
     m_tickets.push_front(ticket);
 
@@ -1340,7 +1393,7 @@ MDL_context::try_acquire_lock(MDL_reques
   {
     /* We can't get here if we allocated a new lock. */
     DBUG_ASSERT(! lock->is_empty());
-    rw_pr_unlock(&lock->m_rwlock);
+    mysql_prlock_unlock(&lock->m_rwlock);
     MDL_ticket::destroy(ticket);
   }
 
@@ -1381,9 +1434,9 @@ MDL_context::clone_ticket(MDL_request *m
   ticket->m_lock= mdl_request->ticket->m_lock;
   mdl_request->ticket= ticket;
 
-  rw_pr_wrlock(&ticket->m_lock->m_rwlock);
+  mysql_prlock_wrlock(&ticket->m_lock->m_rwlock);
   ticket->m_lock->m_granted.add_ticket(ticket);
-  rw_pr_unlock(&ticket->m_lock->m_rwlock);
+  mysql_prlock_unlock(&ticket->m_lock->m_rwlock);
 
   m_tickets.push_front(ticket);
 
@@ -1489,7 +1542,7 @@ bool MDL_context::acquire_lock_impl(MDL_
     if (ticket->is_upgradable_or_exclusive())
       lock->notify_shared_locks(this);
 
-    rw_pr_unlock(&lock->m_rwlock);
+    mysql_prlock_unlock(&lock->m_rwlock);
 
     set_deadlock_weight(mdl_request->get_deadlock_weight());
     will_wait_for(ticket);
@@ -1524,7 +1577,7 @@ bool MDL_context::acquire_lock_impl(MDL_
         my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
       return TRUE;
     }
-    rw_pr_wrlock(&lock->m_rwlock);
+    mysql_prlock_wrlock(&lock->m_rwlock);
   }
 
   lock->m_waiting.remove_ticket(ticket);
@@ -1534,7 +1587,7 @@ bool MDL_context::acquire_lock_impl(MDL_
     (*lock->cached_object_release_hook)(lock->cached_object);
   lock->cached_object= NULL;
 
-  rw_pr_unlock(&lock->m_rwlock);
+  mysql_prlock_unlock(&lock->m_rwlock);
 
   m_tickets.push_front(ticket);
 
@@ -1679,7 +1732,7 @@ MDL_context::upgrade_shared_lock_to_excl
   is_new_ticket= ! has_lock(mdl_svp, mdl_xlock_request.ticket);
 
   /* Merge the acquired and the original lock. @todo: move to a method. */
-  rw_pr_wrlock(&mdl_ticket->m_lock->m_rwlock);
+  mysql_prlock_wrlock(&mdl_ticket->m_lock->m_rwlock);
   if (is_new_ticket)
     mdl_ticket->m_lock->m_granted.remove_ticket(mdl_xlock_request.ticket);
   /*
@@ -1691,7 +1744,7 @@ MDL_context::upgrade_shared_lock_to_excl
   mdl_ticket->m_type= MDL_EXCLUSIVE;
   mdl_ticket->m_lock->m_granted.add_ticket(mdl_ticket);
 
-  rw_pr_unlock(&mdl_ticket->m_lock->m_rwlock);
+  mysql_prlock_unlock(&mdl_ticket->m_lock->m_rwlock);
 
   if (is_new_ticket)
   {
@@ -1709,7 +1762,7 @@ bool MDL_lock::find_deadlock(MDL_ticket
   MDL_ticket *ticket;
   bool result= FALSE;
 
-  rw_pr_rdlock(&m_rwlock);
+  mysql_prlock_rdlock(&m_rwlock);
 
   Ticket_iterator granted_it(m_granted);
   Ticket_iterator waiting_it(m_waiting);
@@ -1761,7 +1814,7 @@ bool MDL_lock::find_deadlock(MDL_ticket
   }
 
 end:
-  rw_pr_unlock(&m_rwlock);
+  mysql_prlock_unlock(&m_rwlock);
   return result;
 }
 
@@ -1770,7 +1823,7 @@ bool MDL_context::find_deadlock(Deadlock
 {
   bool result= FALSE;
 
-  rw_pr_rdlock(&m_waiting_for_lock);
+  mysql_prlock_rdlock(&m_waiting_for_lock);
 
   if (m_waiting_for)
   {
@@ -1799,14 +1852,14 @@ bool MDL_context::find_deadlock(Deadlock
       deadlock_ctx->victim= this;
     else if (deadlock_ctx->victim->m_deadlock_weight >= m_deadlock_weight)
     {
-      rw_pr_unlock(&deadlock_ctx->victim->m_waiting_for_lock);
+      mysql_prlock_unlock(&deadlock_ctx->victim->m_waiting_for_lock);
       deadlock_ctx->victim= this;
     }
     else
-      rw_pr_unlock(&m_waiting_for_lock);
+      mysql_prlock_unlock(&m_waiting_for_lock);
   }
   else
-    rw_pr_unlock(&m_waiting_for_lock);
+    mysql_prlock_unlock(&m_waiting_for_lock);
 
   return result;
 }
@@ -1832,7 +1885,7 @@ bool MDL_context::find_deadlock()
     if (deadlock_ctx.victim != this)
     {
       deadlock_ctx.victim->awake(VICTIM_WAKE_UP);
-      rw_pr_unlock(&deadlock_ctx.victim->m_waiting_for_lock);
+      mysql_prlock_unlock(&deadlock_ctx.victim->m_waiting_for_lock);
       /*
         After adding new arc to waiting graph we found that it participates
         in some loop (i.e. there is a deadlock). We decided to destroy this
@@ -1845,7 +1898,7 @@ bool MDL_context::find_deadlock()
     else
     {
       DBUG_ASSERT(&deadlock_ctx.victim->m_waiting_for_lock == &m_waiting_for_lock);
-      rw_pr_unlock(&deadlock_ctx.victim->m_waiting_for_lock);
+      mysql_prlock_unlock(&deadlock_ctx.victim->m_waiting_for_lock);
       return TRUE;
     }
   }
@@ -1902,14 +1955,14 @@ MDL_context::wait_for_lock(MDL_request *
 
     if (lock->can_grant_lock(mdl_request->type, this))
     {
-      rw_pr_unlock(&lock->m_rwlock);
+      mysql_prlock_unlock(&lock->m_rwlock);
       return FALSE;
     }
 
     MDL_ticket *pending_ticket;
     if (! (pending_ticket= MDL_ticket::create(this, mdl_request->type)))
     {
-      rw_pr_unlock(&lock->m_rwlock);
+      mysql_prlock_unlock(&lock->m_rwlock);
       return TRUE;
     }
 
@@ -1918,7 +1971,7 @@ MDL_context::wait_for_lock(MDL_request *
     lock->m_waiting.add_ticket(pending_ticket);
 
     wait_reset();
-    rw_pr_unlock(&lock->m_rwlock);
+    mysql_prlock_unlock(&lock->m_rwlock);
 
     set_deadlock_weight(MDL_DEADLOCK_WEIGHT_DML);
     will_wait_for(pending_ticket);
@@ -2069,7 +2122,7 @@ void MDL_ticket::downgrade_exclusive_loc
   if (m_type != MDL_EXCLUSIVE)
     return;
 
-  rw_pr_wrlock(&m_lock->m_rwlock);
+  mysql_prlock_wrlock(&m_lock->m_rwlock);
   /*
     To update state of MDL_lock object correctly we need to temporarily
     exclude ticket from the granted queue and then include it back.
@@ -2078,7 +2131,7 @@ void MDL_ticket::downgrade_exclusive_loc
   m_type= type;
   m_lock->m_granted.add_ticket(this);
   m_lock->wake_up_waiters();
-  rw_pr_unlock(&m_lock->m_rwlock);
+  mysql_prlock_unlock(&m_lock->m_rwlock);
 }
 
 

=== modified file 'sql/mdl.h'
--- a/sql/mdl.h	2010-03-01 18:08:17 +0000
+++ b/sql/mdl.h	2010-03-07 18:54:05 +0000
@@ -628,7 +628,7 @@ private:
           important as deadlock detector won't work correctly
           otherwise. @sa Comment for MDL_lock::m_rwlock.
   */
-  rw_pr_lock_t m_waiting_for_lock;
+  mysql_prlock_t m_waiting_for_lock;
   MDL_ticket *m_waiting_for;
   uint m_deadlock_weight;
   /**
@@ -652,9 +652,9 @@ private:
 
   void will_wait_for(MDL_ticket *pending_ticket)
   {
-    rw_pr_wrlock(&m_waiting_for_lock);
+    mysql_prlock_wrlock(&m_waiting_for_lock);
     m_waiting_for= pending_ticket;
-    rw_pr_unlock(&m_waiting_for_lock);
+    mysql_prlock_unlock(&m_waiting_for_lock);
   }
 
   void set_deadlock_weight(uint weight)
@@ -670,9 +670,9 @@ private:
 
   void stop_waiting()
   {
-    rw_pr_wrlock(&m_waiting_for_lock);
+    mysql_prlock_wrlock(&m_waiting_for_lock);
     m_waiting_for= NULL;
-    rw_pr_unlock(&m_waiting_for_lock);
+    mysql_prlock_unlock(&m_waiting_for_lock);
   }
 
   void wait_reset()

=== modified file 'storage/perfschema/pfs_instr.cc'
--- a/storage/perfschema/pfs_instr.cc	2010-03-02 00:17:51 +0000
+++ b/storage/perfschema/pfs_instr.cc	2010-03-07 18:54:05 +0000
@@ -746,6 +746,26 @@ find_or_create_file(PFS_thread *thread,
     }
   }
 
+  char safe_buffer[FN_REFLEN];
+  const char *safe_filename;
+
+  if (len >= FN_REFLEN)
+  {
+    /*
+      The instrumented code uses file names that exceeds FN_REFLEN.
+      This could be legal for instrumentation on non mysys APIs,
+      so we support it.
+      Truncate the file name so that:
+      - it fits into pfs->m_filename
+      - it is safe to use mysys apis to normalize the file name.
+    */
+    memcpy(safe_buffer, filename, FN_REFLEN - 2);
+    safe_buffer[FN_REFLEN - 1]= 0;
+    safe_filename= safe_buffer;
+  }
+  else
+    safe_filename= filename;
+
   /*
     Normalize the file name to avoid duplicates when using aliases:
     - absolute or relative paths
@@ -759,7 +779,7 @@ find_or_create_file(PFS_thread *thread,
     Ignore errors, the file may not exist.
     my_realpath always provide a best effort result in buffer.
   */
-  (void) my_realpath(buffer, filename, MYF(0));
+  (void) my_realpath(buffer, safe_filename, MYF(0));
 
   normalized_filename= buffer;
   normalized_length= strlen(normalized_filename);

=== modified file 'storage/perfschema/unittest/pfs-t.cc'
--- a/storage/perfschema/unittest/pfs-t.cc	2010-01-12 01:48:52 +0000
+++ b/storage/perfschema/unittest/pfs-t.cc	2010-03-07 18:54:05 +0000
@@ -37,14 +37,25 @@ PFS_file* lookup_file_by_name(const char
   uint i;
   PFS_file *pfs;
   uint len= strlen(name);
+  size_t dirlen;
+  const char *filename;
+  uint filename_length;;
 
   for (i= 0; i < file_max; i++)
   {
     pfs= & file_array[i];
     if (pfs->m_lock.is_populated())
     {
-      if ((len == pfs->m_filename_length) &&
-          (strncmp(name, pfs->m_filename, pfs->m_filename_length) == 0))
+      /*
+        When a file "foo" is instrumented, the name is normalized
+        to "/path/to/current/directory/foo", so we remove the
+        directory name here to find it back.
+      */
+      dirlen= dirname_length(pfs->m_filename);
+      filename= pfs->m_filename + dirlen;
+      filename_length= pfs->m_filename_length - dirlen;
+      if ((len == filename_length) &&
+          (strncmp(name, filename, filename_length) == 0))
         return pfs;
     }
   }


Attachment: [text/bzr-bundle] bzr/marc.alff@oracle.com-20100307185405-y64369sty42wm5ha.bundle
Thread
bzr commit into mysql-6.0-codebase-bugfixing branch (marc.alff:3796) Marc Alff7 Mar