From: Christopher Powers Date: August 3 2010 9:14pm Subject: bzr commit into mysql-next-mr-wl4896 branch (chris.powers:3156) List-Archive: http://lists.mysql.com/commits/114967 Message-Id: <20100803211425.D93321DB030E@xeno.mysql.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============5683958773542774944==" --===============5683958773542774944== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/cpowers/work/dev/base-wl4896/mysql/ based on revid:chris.powers@stripped 3156 Christopher Powers 2010-08-03 merge modified: include/mysql/psi/mysql_file.h include/mysql/psi/mysql_thread.h include/mysql/psi/psi.h include/mysql/psi/psi_abi_v1.h include/mysql/psi/psi_abi_v2.h storage/perfschema/CMakeLists.txt storage/perfschema/Makefile.am storage/perfschema/ha_perfschema.cc storage/perfschema/pfs.cc storage/perfschema/pfs_column_types.h storage/perfschema/pfs_events_waits.h storage/perfschema/pfs_instr.cc storage/perfschema/pfs_instr.h storage/perfschema/pfs_instr_class.cc storage/perfschema/pfs_instr_class.h storage/perfschema/pfs_server.h storage/perfschema/table_all_instr.h storage/perfschema/table_events_waits.cc storage/perfschema/table_events_waits.h storage/perfschema/table_events_waits_summary.h storage/perfschema/table_setup_instruments.cc storage/perfschema/table_setup_instruments.h storage/perfschema/table_setup_objects.cc storage/perfschema/table_setup_objects.h === modified file 'include/mysql/psi/mysql_file.h' --- a/include/mysql/psi/mysql_file.h 2010-03-31 14:05:33 +0000 +++ b/include/mysql/psi/mysql_file.h 2010-08-03 21:14:19 +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 @@ -10,8 +10,8 @@ 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 */ + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ #ifndef MYSQL_FILE_H #define MYSQL_FILE_H @@ -506,9 +506,10 @@ inline_mysql_file_fgets( char *result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_READ); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) size, src_file, src_line); @@ -532,9 +533,10 @@ inline_mysql_file_fgetc( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_READ); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line); @@ -558,10 +560,11 @@ inline_mysql_file_fputs( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; size_t bytes= 0; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_WRITE); if (likely(locker != NULL)) { @@ -588,9 +591,10 @@ inline_mysql_file_fputc( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_WRITE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line); @@ -614,9 +618,10 @@ inline_mysql_file_fprintf(MYSQL_FILE *fi va_list args; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_WRITE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, __FILE__, __LINE__); @@ -642,9 +647,10 @@ inline_mysql_file_vfprintf( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_WRITE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -668,9 +674,10 @@ inline_mysql_file_fflush( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_FLUSH); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -700,9 +707,10 @@ inline_mysql_file_fstat( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(filenr, + locker= PSI_server->get_thread_file_descriptor_locker(&state, filenr, PSI_FILE_FSTAT); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -726,9 +734,11 @@ inline_mysql_file_stat( MY_STAT *result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_STAT, + locker= PSI_server->get_thread_file_name_locker(&state, + key, PSI_FILE_STAT, path, &locker); if (likely(locker != NULL)) PSI_server->start_file_open_wait(locker, src_file, src_line); @@ -752,9 +762,10 @@ inline_mysql_file_chsize( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_CHSIZE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) newlength, src_file, @@ -784,10 +795,11 @@ inline_mysql_file_fopen( { #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { locker= PSI_server->get_thread_file_name_locker - (key, PSI_FILE_STREAM_OPEN, filename, that); + (&state, key, PSI_FILE_STREAM_OPEN, filename, that); if (likely(locker != NULL)) that->m_psi= PSI_server->start_file_open_wait(locker, src_file, src_line); @@ -800,7 +812,7 @@ inline_mysql_file_fopen( #endif if (unlikely(that->m_file == NULL)) { - my_free(that, MYF(0)); + my_free(that); return NULL; } } @@ -820,10 +832,11 @@ inline_mysql_file_fclose( { #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; DBUG_ASSERT(file != NULL); if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_STREAM_CLOSE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -834,7 +847,7 @@ inline_mysql_file_fclose( if (likely(locker != NULL)) PSI_server->end_file_wait(locker, (size_t) 0); #endif - my_free(file, MYF(0)); + my_free(file); } return result; } @@ -849,9 +862,10 @@ inline_mysql_file_fread( size_t result= 0; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_READ); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, count, src_file, src_line); @@ -882,9 +896,10 @@ inline_mysql_file_fwrite( size_t result= 0; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_WRITE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, count, src_file, src_line); @@ -915,9 +930,10 @@ inline_mysql_file_fseek( my_off_t result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_SEEK); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -941,9 +957,10 @@ inline_mysql_file_ftell( my_off_t result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server && file->m_psi)) { - locker= PSI_server->get_thread_file_stream_locker(file->m_psi, + locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi, PSI_FILE_TELL); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -967,9 +984,10 @@ inline_mysql_file_create( File file; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE, + locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_CREATE, filename, &locker); if (likely(locker != NULL)) PSI_server->start_file_open_wait(locker, src_file, src_line); @@ -1014,9 +1032,10 @@ inline_mysql_file_open( File file; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_OPEN, + locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_OPEN, filename, &locker); if (likely(locker != NULL)) PSI_server->start_file_open_wait(locker, src_file, src_line); @@ -1040,9 +1059,10 @@ inline_mysql_file_close( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_CLOSE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -1066,9 +1086,10 @@ inline_mysql_file_read( size_t result= 0; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_READ); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, count, src_file, src_line); @@ -1099,9 +1120,10 @@ inline_mysql_file_write( size_t result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_WRITE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, count, src_file, src_line); @@ -1132,9 +1154,10 @@ inline_mysql_file_pread( size_t result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_READ); + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_READ); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, count, src_file, src_line); } @@ -1164,9 +1187,10 @@ inline_mysql_file_pwrite( size_t result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_WRITE); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, count, src_file, src_line); @@ -1197,9 +1221,10 @@ inline_mysql_file_seek( my_off_t result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_SEEK); + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_SEEK); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); } @@ -1222,9 +1247,10 @@ inline_mysql_file_tell( my_off_t result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_TELL); + locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_TELL); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); } @@ -1247,9 +1273,10 @@ inline_mysql_file_delete( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE, + locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_DELETE, name, &locker); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -1273,9 +1300,10 @@ inline_mysql_file_rename( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME, + locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_RENAME, to, &locker); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -1300,9 +1328,10 @@ inline_mysql_file_create_with_symlink( File file; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE, + locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_CREATE, filename, &locker); if (likely(locker != NULL)) PSI_server->start_file_open_wait(locker, src_file, src_line); @@ -1327,9 +1356,10 @@ inline_mysql_file_delete_with_symlink( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE, + locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_DELETE, name, &locker); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -1353,9 +1383,10 @@ inline_mysql_file_rename_with_symlink( int result; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME, + locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_RENAME, to, &locker); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); @@ -1379,9 +1410,10 @@ inline_mysql_file_sync( int result= 0; #ifdef HAVE_PSI_INTERFACE struct PSI_file_locker *locker= NULL; + PSI_file_locker_state state; if (likely(PSI_server != NULL)) { - locker= PSI_server->get_thread_file_descriptor_locker(fd, PSI_FILE_SYNC); + locker= PSI_server->get_thread_file_descriptor_locker(&state, fd, PSI_FILE_SYNC); if (likely(locker != NULL)) PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line); } === modified file 'include/mysql/psi/mysql_thread.h' --- a/include/mysql/psi/mysql_thread.h 2010-03-09 18:03:02 +0000 +++ b/include/mysql/psi/mysql_thread.h 2010-08-03 21:14:19 +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 @@ -10,8 +10,8 @@ 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 */ + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ #ifndef MYSQL_THREAD_H #define MYSQL_THREAD_H @@ -625,9 +625,10 @@ static inline int inline_mysql_mutex_loc int result; #ifdef HAVE_PSI_INTERFACE struct PSI_mutex_locker *locker= NULL; + PSI_mutex_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_LOCK); + locker= PSI_server->get_thread_mutex_locker(&state, that->m_psi, PSI_MUTEX_LOCK); if (likely(locker != NULL)) PSI_server->start_mutex_wait(locker, src_file, src_line); } @@ -654,9 +655,10 @@ static inline int inline_mysql_mutex_try int result; #ifdef HAVE_PSI_INTERFACE struct PSI_mutex_locker *locker= NULL; + PSI_mutex_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_TRYLOCK); + locker= PSI_server->get_thread_mutex_locker(&state, that->m_psi, PSI_MUTEX_TRYLOCK); if (likely(locker != NULL)) PSI_server->start_mutex_wait(locker, src_file, src_line); } @@ -682,13 +684,8 @@ static inline int inline_mysql_mutex_unl { 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_mutex(thread, that->m_psi); - } + PSI_server->unlock_mutex(that->m_psi); #endif #ifdef SAFE_MUTEX result= safe_mutex_unlock(&that->m_mutex, src_file, src_line); @@ -771,9 +768,10 @@ static inline int inline_mysql_rwlock_rd int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_READLOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_rdwait(locker, src_file, src_line); @@ -798,9 +796,10 @@ static inline int inline_mysql_prlock_rd int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_READLOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_rdwait(locker, src_file, src_line); @@ -825,9 +824,10 @@ static inline int inline_mysql_rwlock_wr int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_WRITELOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_wrwait(locker, src_file, src_line); @@ -852,9 +852,10 @@ static inline int inline_mysql_prlock_wr int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_WRITELOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_wrwait(locker, src_file, src_line); @@ -879,9 +880,10 @@ static inline int inline_mysql_rwlock_tr int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_TRYREADLOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_rdwait(locker, src_file, src_line); @@ -906,9 +908,10 @@ static inline int inline_mysql_prlock_tr int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_TRYREADLOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_rdwait(locker, src_file, src_line); @@ -933,9 +936,10 @@ static inline int inline_mysql_rwlock_tr int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_TRYWRITELOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_wrwait(locker, src_file, src_line); @@ -960,9 +964,10 @@ static inline int inline_mysql_prlock_tr int result; #ifdef HAVE_PSI_INTERFACE struct PSI_rwlock_locker *locker= NULL; + PSI_rwlock_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_rwlock_locker(that->m_psi, + locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, PSI_RWLOCK_TRYWRITELOCK); if (likely(locker != NULL)) PSI_server->start_rwlock_wrwait(locker, src_file, src_line); @@ -982,13 +987,8 @@ static inline int inline_mysql_rwlock_un { 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); - } + PSI_server->unlock_rwlock(that->m_psi); #endif result= rw_unlock(&that->m_rwlock); return result; @@ -1000,13 +1000,8 @@ static inline int inline_mysql_prlock_un { 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); - } + PSI_server->unlock_rwlock(that->m_psi); #endif result= rw_pr_unlock(&that->m_prlock); return result; @@ -1053,9 +1048,10 @@ static inline int inline_mysql_cond_wait int result; #ifdef HAVE_PSI_INTERFACE struct PSI_cond_locker *locker= NULL; + PSI_cond_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi, + locker= PSI_server->get_thread_cond_locker(&state, that->m_psi, mutex->m_psi, PSI_COND_WAIT); if (likely(locker != NULL)) PSI_server->start_cond_wait(locker, src_file, src_line); @@ -1081,9 +1077,10 @@ static inline int inline_mysql_cond_time int result; #ifdef HAVE_PSI_INTERFACE struct PSI_cond_locker *locker= NULL; + PSI_cond_locker_state state; if (likely(PSI_server && that->m_psi)) { - locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi, + locker= PSI_server->get_thread_cond_locker(&state, that->m_psi, mutex->m_psi, PSI_COND_TIMEDWAIT); if (likely(locker != NULL)) PSI_server->start_cond_wait(locker, src_file, src_line); @@ -1102,13 +1099,8 @@ static inline int inline_mysql_cond_sign { 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->signal_cond(thread, that->m_psi); - } + PSI_server->signal_cond(that->m_psi); #endif result= pthread_cond_signal(&that->m_cond); return result; @@ -1119,13 +1111,8 @@ static inline int inline_mysql_cond_broa { 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->broadcast_cond(thread, that->m_psi); - } + PSI_server->broadcast_cond(that->m_psi); #endif result= pthread_cond_broadcast(&that->m_cond); return result; === modified file 'include/mysql/psi/psi.h' --- a/include/mysql/psi/psi.h 2010-07-29 19:56:17 +0000 +++ b/include/mysql/psi/psi.h 2010-08-03 21:14:19 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2010 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 @@ -10,8 +10,8 @@ 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 */ + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ #ifndef MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H #define MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H @@ -29,6 +29,8 @@ C_MODE_START +struct TABLE_SHARE; + /** @file mysql/psi/psi.h Performance schema instrumentation interface. @@ -86,6 +88,12 @@ struct PSI_file; */ struct PSI_socket; +/** + Interface for an instrumented table operation. + This is an opaque structure. +*/ +struct PSI_table_locker; + /** Entry point for the performance schema interface. */ struct PSI_bootstrap { @@ -235,6 +243,23 @@ enum PSI_file_operation PSI_FILE_SYNC= 16 }; +/** Operation performed on an instrumented table. */ +enum PSI_table_operation +{ + /** Table lock, in the server layer. */ + PSI_TABLE_LOCK= 0, + /** Table lock, in the storage engine layer. */ + PSI_TABLE_EXTERNAL_LOCK= 1, + /** Row fetch. */ + PSI_TABLE_FETCH_ROW= 2, + /** Row write. */ + PSI_TABLE_WRITE_ROW= 3, + /** Row update. */ + PSI_TABLE_UPDATE_ROW= 4, + /** Row delete. */ + PSI_TABLE_DELETE_ROW= 5 +}; + /** Operation performed on an instrumented socket. */ enum PSI_socket_operation { @@ -269,13 +294,6 @@ enum PSI_socket_operation PSI_SOCKET_SHUTDOWN= 9 }; - -/** - Interface for an instrumented table operation. - This is an opaque structure. -*/ -struct PSI_table_locker; - /** Instrumented mutex key. To instrument a mutex, a mutex key must be obtained using @c register_mutex. @@ -492,6 +510,175 @@ struct PSI_socket_info_v1 int m_flags; }; +/** + State data storage for @c get_thread_mutex_locker_v1_t. + This structure provide temporary storage to a mutex locker. + The content of this structure is considered opaque, + the fields are only hints of what an implementation + of the psi interface can use. + This memory is provided by the instrumented code for performance reasons. + @sa get_thread_mutex_locker_v1_t +*/ +struct PSI_mutex_locker_state_v1 +{ + /** Internal state. */ + uint m_flags; + /** Current mutex. */ + struct PSI_mutex *m_mutex; + /** Current thread. */ + struct PSI_thread *m_thread; + /** Timer start. */ + ulonglong m_timer_start; + /** Timer function. */ + ulonglong (*m_timer)(void); + /** Current operation. */ + enum PSI_mutex_operation m_operation; + /** Source file. */ + const char* m_src_file; + /** Source line number. */ + int m_src_line; + /** Internal data. */ + void *m_wait; +}; + +/** + State data storage for @c get_thread_rwlock_locker_v1_t. + This structure provide temporary storage to a rwlock locker. + The content of this structure is considered opaque, + the fields are only hints of what an implementation + of the psi interface can use. + This memory is provided by the instrumented code for performance reasons. + @sa get_thread_rwlock_locker_v1_t +*/ +struct PSI_rwlock_locker_state_v1 +{ + /** Internal state. */ + uint m_flags; + /** Current rwlock. */ + struct PSI_rwlock *m_rwlock; + /** Current thread. */ + struct PSI_thread *m_thread; + /** Timer start. */ + ulonglong m_timer_start; + /** Timer function. */ + ulonglong (*m_timer)(void); + /** Current operation. */ + enum PSI_rwlock_operation m_operation; + /** Source file. */ + const char* m_src_file; + /** Source line number. */ + int m_src_line; + /** Internal data. */ + void *m_wait; +}; + +/** + State data storage for @c get_thread_cond_locker_v1_t. + This structure provide temporary storage to a condition locker. + The content of this structure is considered opaque, + the fields are only hints of what an implementation + of the psi interface can use. + This memory is provided by the instrumented code for performance reasons. + @sa get_thread_cond_locker_v1_t +*/ +struct PSI_cond_locker_state_v1 +{ + /** Internal state. */ + uint m_flags; + /** Current condition. */ + struct PSI_cond *m_cond; + /** Current mutex. */ + struct PSI_mutex *m_mutex; + /** Current thread. */ + struct PSI_thread *m_thread; + /** Timer start. */ + ulonglong m_timer_start; + /** Timer function. */ + ulonglong (*m_timer)(void); + /** Current operation. */ + enum PSI_cond_operation m_operation; + /** Source file. */ + const char* m_src_file; + /** Source line number. */ + int m_src_line; + /** Internal data. */ + void *m_wait; +}; + +/** + State data storage for @c get_thread_file_name_locker_v1_t. + This structure provide temporary storage to a file locker. + The content of this structure is considered opaque, + the fields are only hints of what an implementation + of the psi interface can use. + This memory is provided by the instrumented code for performance reasons. + @sa get_thread_file_name_locker_v1_t + @sa get_thread_file_stream_locker_v1_t + @sa get_thread_file_descriptor_locker_v1_t +*/ +struct PSI_file_locker_state_v1 +{ + /** Internal state. */ + uint m_flags; + /** Current file. */ + struct PSI_file *m_file; + /** Current thread. */ + struct PSI_thread *m_thread; + /** Operation number of bytes. */ + size_t m_number_of_bytes; + /** Timer start. */ + ulonglong m_timer_start; + /** Timer function. */ + ulonglong (*m_timer)(void); + /** Current operation. */ + enum PSI_file_operation m_operation; + /** Source file. */ + const char* m_src_file; + /** Source line number. */ + int m_src_line; + /** Internal data. */ + void *m_wait; +}; + +/** + State data storage for @c get_thread_table_locker_v1_t. + This structure provide temporary storage to a table locker. + The content of this structure is considered opaque, + the fields are only hints of what an implementation + of the psi interface can use. + This memory is provided by the instrumented code for performance reasons. + @sa get_thread_table_locker_v1_t +*/ +struct PSI_table_locker_state_v1 +{ + /** Internal state. */ + uint m_flags; + /** Current table handle. */ + struct PSI_table *m_table; + /** Current table share. */ + struct PSI_table_share *m_table_share; + /** Instrumentation class. */ + void *m_class; + /** Current thread. */ + struct PSI_thread *m_thread; + /** Timer start. */ + ulonglong m_timer_start; + /** Timer function. */ + ulonglong (*m_timer)(void); + /** Current operation. */ + enum PSI_table_operation m_operation; + /** Current table io index. */ + uint m_index; + /** Current table lock index. */ + uint m_lock_index; + /** Source file. */ + const char* m_src_file; + /** Source line number. */ + int m_src_line; + /** Internal data. */ + void *m_wait; +}; + /* Using typedef to make reuse between PSI_v1 and PSI_v2 easier later. */ /** @@ -594,6 +781,15 @@ typedef struct PSI_cond* (*init_cond_v1_ typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond); /** + Acquire a table share instrumentation. + @param temporary True for temporary tables + @param share The SQL layer table share + @return a table share instrumentation, or NULL +*/ +typedef struct PSI_table_share* (*get_table_share_v1_t) + (my_bool temporary, struct TABLE_SHARE *share); + +/** Socket instrumentation initialisation API. @param key the registered mutex key @param identity the address of the socket itself @@ -608,26 +804,23 @@ typedef struct PSI_socket* (*init_socket */ typedef void (*destroy_socket_v1_t)(struct PSI_socket *socket); -/** - Acquire a table info by name. - @param schema_name name of the table schema - @param schema_name_length length of schema_name - @param table_name name of the table - @param table_name_length length of table_name - @param identity table identity pointer, typically the table share - @return a table info, or NULL if the table is not instrumented -*/ -typedef struct PSI_table_share* (*get_table_share_v1_t) - (const char *schema_name, int schema_name_length, const char *table_name, - int table_name_length, const void *identity); - -/** Release a table share. @param info the table share to release */ typedef void (*release_table_share_v1_t)(struct PSI_table_share *share); /** + Drop a table share. + @param schema_name the table schema name + @param schema_name_length the table schema name length + @param table_name the table name + @param table_name_length the table name length +*/ +typedef void (*drop_table_share_v1_t) + (const char *schema_name, int schema_name_length, + const char *table_name, int table_name_length); + +/** Open an instrumentation table handle. @param share the table to open @param identity table handle identity @@ -713,40 +906,53 @@ typedef void (*delete_thread_v1_t)(struc /** Get a mutex instrumentation locker. + @param state data storage for the locker @param mutex the instrumented mutex to lock @return a mutex locker, or NULL */ typedef struct PSI_mutex_locker* (*get_thread_mutex_locker_v1_t) - (struct PSI_mutex *mutex, enum PSI_mutex_operation op); + (struct PSI_mutex_locker_state_v1 *state, + struct PSI_mutex *mutex, + enum PSI_mutex_operation op); /** Get a rwlock instrumentation locker. + @param state data storage for the locker @param rwlock the instrumented rwlock to lock @return a rwlock locker, or NULL */ typedef struct PSI_rwlock_locker* (*get_thread_rwlock_locker_v1_t) - (struct PSI_rwlock *rwlock, enum PSI_rwlock_operation op); + (struct PSI_rwlock_locker_state_v1 *state, + struct PSI_rwlock *rwlock, + enum PSI_rwlock_operation op); /** Get a cond instrumentation locker. + @param state data storage for the locker @param cond the instrumented condition to wait on @param mutex the instrumented mutex associated with the condition @return a condition locker, or NULL */ typedef struct PSI_cond_locker* (*get_thread_cond_locker_v1_t) - (struct PSI_cond *cond, struct PSI_mutex *mutex, + (struct PSI_cond_locker_state_v1 *state, + struct PSI_cond *cond, struct PSI_mutex *mutex, enum PSI_cond_operation op); /** Get a table instrumentation locker. + @param state data storage for the locker @param table the instrumented table to lock + @param op the operation to be performed + @param flags Per operation flags @return a table locker, or NULL */ typedef struct PSI_table_locker* (*get_thread_table_locker_v1_t) - (struct PSI_table *table); + (struct PSI_table_locker_state_v1 *state, + struct PSI_table *table, enum PSI_table_operation op, ulong flags); /** Get a file instrumentation locker, for opening or creating a file. + @param state data storage for the locker @param key the file instrumentation key @param op the operation to perform @param name the file name @@ -754,27 +960,31 @@ typedef struct PSI_table_locker* (*get_t @return a file locker, or NULL */ typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t) - (PSI_file_key key, enum PSI_file_operation op, const char *name, + (struct PSI_file_locker_state_v1 *state, + PSI_file_key key, enum PSI_file_operation op, const char *name, const void *identity); /** Get a file stream instrumentation locker. + @param state data storage for the locker @param file the file stream to access @param op the operation to perform @return a file locker, or NULL */ typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t) - (struct PSI_file *file, enum PSI_file_operation op); + (struct PSI_file_locker_state_v1 *state, + struct PSI_file *file, enum PSI_file_operation op); /** Get a file instrumentation locker. + @param state data storage for the locker @param file the file descriptor to access @param op the operation to perform @return a file locker, or NULL */ typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t) - (File file, enum PSI_file_operation op); - + (struct PSI_file_locker_state_v1 *state, + File file, enum PSI_file_operation op); /** Get a socket instrumentation locker. @param socket the socket to access @@ -786,35 +996,31 @@ typedef struct PSI_socket_locker* (*get_ /** Record a mutex instrumentation unlock event. - @param thread the running thread instrumentation @param mutex the mutex instrumentation */ typedef void (*unlock_mutex_v1_t) - (struct PSI_thread *thread, struct PSI_mutex *mutex); + (struct PSI_mutex *mutex); /** Record a rwlock instrumentation unlock event. - @param thread the running thread instrumentation @param rwlock the rwlock instrumentation */ typedef void (*unlock_rwlock_v1_t) - (struct PSI_thread *thread, struct PSI_rwlock *rwlock); + (struct PSI_rwlock *rwlock); /** Record a condition instrumentation signal event. - @param thread the running thread instrumentation @param cond the cond instrumentation */ typedef void (*signal_cond_v1_t) - (struct PSI_thread *thread, struct PSI_cond *cond); + (struct PSI_cond *cond); /** Record a condition instrumentation broadcast event. - @param thread the running thread instrumentation @param cond the cond instrumentation */ typedef void (*broadcast_cond_v1_t) - (struct PSI_thread *thread, struct PSI_cond *cond); + (struct PSI_cond *cond); /** Record a mutex instrumentation wait start event. @@ -882,11 +1088,12 @@ typedef void (*end_cond_wait_v1_t) /** Record a table instrumentation wait start event. @param locker a table locker for the running thread + @param index the index used if any, or MAX_KEY @param file the source file name @param line the source line number */ typedef void (*start_table_wait_v1_t) - (struct PSI_table_locker *locker, const char *src_file, uint src_line); + (struct PSI_table_locker *locker, uint index, const char *src_file, uint src_line); /** Record a table instrumentation wait end event. @@ -1032,6 +1239,8 @@ struct PSI_v1 get_table_share_v1_t get_table_share; /** @sa release_table_share_v1_t. */ release_table_share_v1_t release_table_share; + /** @sa drop_table_share_v1_t. */ + drop_table_share_v1_t drop_table_share; /** @sa open_table_v1_t. */ open_table_v1_t open_table; /** @sa close_table_v1_t. */ @@ -1182,6 +1391,36 @@ struct PSI_file_info_v2 int placeholder; }; +struct PSI_mutex_locker_state_v2 +{ + /** Placeholder */ + int placeholder; +}; + +struct PSI_rwlock_locker_state_v2 +{ + /** Placeholder */ + int placeholder; +}; + +struct PSI_cond_locker_state_v2 +{ + /** Placeholder */ + int placeholder; +}; + +struct PSI_file_locker_state_v2 +{ + /** Placeholder */ + int placeholder; +}; + +struct PSI_table_locker_state_v2 +{ + /** Placeholder */ + int placeholder; +}; + /** @} (end of group Group_PSI_v2) */ #endif /* HAVE_PSI_2 */ @@ -1226,6 +1465,11 @@ typedef struct PSI_cond_info_v1 PSI_cond typedef struct PSI_thread_info_v1 PSI_thread_info; typedef struct PSI_file_info_v1 PSI_file_info; typedef struct PSI_socket_info_v1 PSI_socket_info; +typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state; +typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state; +typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state; +typedef struct PSI_file_locker_state_v1 PSI_file_locker_state; +typedef struct PSI_table_locker_state_v1 PSI_table_locker_state; #endif #ifdef USE_PSI_2 @@ -1236,6 +1480,11 @@ typedef struct PSI_cond_info_v2 PSI_cond typedef struct PSI_thread_info_v2 PSI_thread_info; typedef struct PSI_file_info_v2 PSI_file_info; typedef struct PSI_socket_info_v2 PSI_socket_info; +typedef struct PSI_mutex_locker_state_v2 PSI_mutex_locker_state; +typedef struct PSI_rwlock_locker_state_v2 PSI_rwlock_locker_state; +typedef struct PSI_cond_locker_state_v2 PSI_cond_locker_state; +typedef struct PSI_file_locker_state_v2 PSI_file_locker_state; +typedef struct PSI_table_locker_state_v2 PSI_table_locker_state; #endif #else /* HAVE_PSI_INTERFACE */ === modified file 'include/mysql/psi/psi_abi_v1.h' --- a/include/mysql/psi/psi_abi_v1.h 2009-12-01 00:49:15 +0000 +++ b/include/mysql/psi/psi_abi_v1.h 2010-08-03 21:14:19 +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 @@ -10,8 +10,8 @@ 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 */ + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ /** @file mysql/psi/psi_abi_v1.h === modified file 'include/mysql/psi/psi_abi_v2.h' --- a/include/mysql/psi/psi_abi_v2.h 2009-12-01 00:49:15 +0000 +++ b/include/mysql/psi/psi_abi_v2.h 2010-08-03 21:14:19 +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 @@ -10,8 +10,8 @@ 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 */ + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ /** @file mysql/psi/psi_abi_v1.h === modified file 'storage/perfschema/CMakeLists.txt' --- a/storage/perfschema/CMakeLists.txt 2010-07-07 19:49:15 +0000 +++ b/storage/perfschema/CMakeLists.txt 2010-08-03 21:14:19 +0000 @@ -10,9 +10,8 @@ # 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include @@ -41,6 +40,7 @@ SET(PERFSCHEMA_SOURCES ha_perfschema.h table_events_waits_summary.h table_file_instances.h table_file_summary.h + table_helper.h table_socket_instances.h table_performance_timers.h table_processlist.h === modified file 'storage/perfschema/Makefile.am' --- a/storage/perfschema/Makefile.am 2010-04-19 12:26:29 +0000 +++ b/storage/perfschema/Makefile.am 2010-08-03 21:14:19 +0000 @@ -10,8 +10,8 @@ # 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA #called from the top level Makefile @@ -37,7 +37,7 @@ noinst_HEADERS = ha_perfschema.h pfs_eng pfs_global.h pfs_instr_class.h pfs_instr.h \ pfs_column_types.h pfs_column_values.h \ table_setup_instruments.h table_performance_timers.h \ - table_setup_timers.h \ + table_setup_timers.h table_helper.h \ table_setup_consumers.h table_events_waits.h \ pfs_events_waits.h pfs_timer.h table_processlist.h \ table_sync_instances.h \ === modified file 'storage/perfschema/ha_perfschema.cc' --- a/storage/perfschema/ha_perfschema.cc 2010-07-09 02:23:31 +0000 +++ b/storage/perfschema/ha_perfschema.cc 2010-08-03 21:14:19 +0000 @@ -148,7 +148,7 @@ mysql_declare_plugin(perfschema) MYSQL_STORAGE_ENGINE_PLUGIN, &pfs_storage_engine, pfs_engine_name, - "Marc Alff, Sun Microsystems", + "Marc Alff, Oracle", /* Formerly Sun Microsystems, formerly MySQL */ "Performance Schema", PLUGIN_LICENSE_GPL, pfs_init_func, /* Plugin Init */ @@ -188,8 +188,6 @@ int ha_perfschema::open(const char *name thr_lock_data_init(m_table_share->m_thr_lock_ptr, &m_thr_lock, NULL); ref_length= m_table_share->m_ref_length; - psi_open(); - DBUG_RETURN(0); } @@ -200,8 +198,6 @@ int ha_perfschema::close(void) delete m_table; m_table= NULL; - psi_close(); - DBUG_RETURN(0); } === modified file 'storage/perfschema/pfs.cc' --- a/storage/perfschema/pfs.cc 2010-07-29 19:56:17 +0000 +++ b/storage/perfschema/pfs.cc 2010-08-03 21:14:19 +0000 @@ -20,6 +20,8 @@ #include #include "my_global.h" +#include "my_pthread.h" +#include "sql_const.h" #include "pfs.h" #include "pfs_instr_class.h" #include "pfs_instr.h" @@ -28,9 +30,6 @@ #include "pfs_timer.h" #include "pfs_events_waits.h" -/* Pending WL#4895 PERFORMANCE_SCHEMA Instrumenting Table IO */ -#undef HAVE_TABLE_WAIT - /** @page PAGE_PERFORMANCE_SCHEMA The Performance Schema main page MySQL PERFORMANCE_SCHEMA implementation. @@ -671,7 +670,7 @@ static inline int mysql_mutex_lock(...) @ingroup Performance_schema @defgroup Performance_schema_tables Performance Schema Tables - @ingroup Performance_schema_implementationf + @ingroup Performance_schema_implementation */ pthread_key(PFS_thread*, THR_PFS); @@ -723,6 +722,20 @@ static enum_operation_type file_operatio }; /** + Conversion map from PSI_table_operation to enum_operation_type. + Indexed by enum PSI_table_operation. +*/ +static enum_operation_type table_operation_map[]= +{ + OPERATION_TYPE_TABLE_LOCK, + OPERATION_TYPE_TABLE_EXTERNAL_LOCK, + OPERATION_TYPE_TABLE_FETCH, + OPERATION_TYPE_TABLE_WRITE_ROW, + OPERATION_TYPE_TABLE_UPDATE_ROW, + OPERATION_TYPE_TABLE_DELETE_ROW +}; + +/** Conversion map from PSI_socket_operation to enum_operation_type. Indexed by enum PSI_socket_operation. */ @@ -936,69 +949,76 @@ static void destroy_cond_v1(PSI_cond* co destroy_cond(pfs); } -static PSI_socket* -init_socket_v1(PSI_socket_key key, const void *identity) +/** + Implementation of the table instrumentation interface. + @sa PSI_v1::get_table_share. +*/ +static PSI_table_share* +get_table_share_v1(my_bool temporary, TABLE_SHARE *share) { -// INIT_BODY_V1(socket, key, identity); - PFS_socket_class *klass; - PFS_socket *pfs; PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); if (unlikely(pfs_thread == NULL)) return NULL; - if (! pfs_thread->m_enabled) + if (! global_table_class.m_enabled) return NULL; - klass= find_socket_class(key); - if (unlikely(klass == NULL)) - return NULL; - if (! klass->m_enabled) - return NULL; - pfs= create_socket(klass, identity); - return reinterpret_cast (pfs); + PFS_table_share* pfs_share; + pfs_share= find_or_create_table_share(pfs_thread, temporary, share); + return reinterpret_cast (pfs_share); } -static void destroy_socket_v1(PSI_socket* socket) -{ - PFS_socket *pfs= reinterpret_cast (socket); - destroy_socket(pfs); -} - -static PSI_table_share* -get_table_share_v1(const char *schema_name, int schema_name_length, - const char *table_name, int table_name_length, - const void *identity) +/** + Implementation of the table instrumentation interface. + @sa PSI_v1::release_table_share. +*/ +static void release_table_share_v1(PSI_table_share* share) { -#ifdef HAVE_TABLE_WAIT + DBUG_ASSERT(share != NULL); PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); if (unlikely(pfs_thread == NULL)) - return NULL; - PFS_table_share* share; - share= find_or_create_table_share(pfs_thread, - schema_name, schema_name_length, - table_name, table_name_length); - return reinterpret_cast (share); -#else - return NULL; -#endif + return; + PFS_table_share* pfs; + pfs= reinterpret_cast (share); + purge_table_share(pfs_thread, pfs); } -static void release_table_share_v1(PSI_table_share* share) +/** + Implementation of the table instrumentation interface. + @sa PSI_v1::drop_table_share. +*/ +static void +drop_table_share_v1(const char *schema_name, int schema_name_length, + const char *table_name, int table_name_length) { - /* - To be implemented by WL#4895 PERFORMANCE_SCHEMA Instrumenting Table IO. - */ + PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + if (unlikely(pfs_thread == NULL)) + return; + /* TODO: temporary tables */ + drop_table_share(pfs_thread, false, schema_name, schema_name_length, + table_name, table_name_length); } +/** + Implementation of the table instrumentation interface. + @sa PSI_v1::open_table. +*/ static PSI_table* open_table_v1(PSI_table_share *share, const void *identity) { + PFS_thread *thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + if (unlikely(thread == NULL)) + return NULL; PFS_table_share *pfs_table_share= reinterpret_cast (share); PFS_table *pfs_table; DBUG_ASSERT(pfs_table_share); - pfs_table= create_table(pfs_table_share, identity); + pfs_table= create_table(pfs_table_share, thread, identity); return reinterpret_cast (pfs_table); } +/** + Implementation of the table instrumentation interface. + @sa PSI_v1::close_table. +*/ static void close_table_v1(PSI_table *table) { PFS_table *pfs= reinterpret_cast (table); @@ -1006,6 +1026,32 @@ static void close_table_v1(PSI_table *ta destroy_table(pfs); } +static PSI_socket* +init_socket_v1(PSI_socket_key key, const void *identity) +{ +// INIT_BODY_V1(socket, key, identity); + PFS_socket_class *klass; + PFS_socket *pfs; + PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); + if (unlikely(pfs_thread == NULL)) + return NULL; + if (! pfs_thread->m_enabled) + return NULL; + klass= find_socket_class(key); + if (unlikely(klass == NULL)) + return NULL; + if (! klass->m_enabled) + return NULL; + pfs= create_socket(klass, identity); + return reinterpret_cast (pfs); +} + +static void destroy_socket_v1(PSI_socket* socket) +{ + PFS_socket *pfs= reinterpret_cast (socket); + destroy_socket(pfs); +} + static void create_file_v1(PSI_file_key key, const char *name, File file) { int index= (int) file; @@ -1064,7 +1110,7 @@ void* pfs_spawn_thread(void *arg) */ user_start_routine= typed_arg->m_user_start_routine; user_arg= typed_arg->m_user_arg; - my_free(typed_arg, MYF(0)); + my_free(typed_arg); /* Then, execute the user code for this thread. */ (*user_start_routine)(user_arg); @@ -1092,7 +1138,7 @@ static int spawn_thread_v1(PSI_thread_ke int result= pthread_create(thread, attr, pfs_spawn_thread, psi_arg); if (unlikely(result != 0)) - my_free(psi_arg, MYF(0)); + my_free(psi_arg); return result; } @@ -1148,7 +1194,8 @@ static void delete_thread_v1(PSI_thread } static PSI_mutex_locker* -get_thread_mutex_locker_v1(PSI_mutex *mutex, PSI_mutex_operation op) +get_thread_mutex_locker_v1(PSI_mutex_locker_state *state, + PSI_mutex *mutex, PSI_mutex_operation op) { PFS_mutex *pfs_mutex= reinterpret_cast (mutex); DBUG_ASSERT((int) op >= 0); @@ -1171,6 +1218,14 @@ get_thread_mutex_locker_v1(PSI_mutex *mu } PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack [pfs_thread->m_wait_locker_count]; + if (likely(pfs_thread->m_wait_locker_count == 0)) + pfs_locker->m_waits_current.m_nesting_event_id= 0; + else + { + PFS_wait_locker *parent_locker= pfs_locker-1; + pfs_locker->m_waits_current.m_nesting_event_id= + parent_locker->m_waits_current.m_event_id; + } pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS; pfs_locker->m_target.m_mutex= pfs_mutex; @@ -1193,15 +1248,14 @@ get_thread_mutex_locker_v1(PSI_mutex *mu } static PSI_rwlock_locker* -get_thread_rwlock_locker_v1(PSI_rwlock *rwlock, PSI_rwlock_operation op) +get_thread_rwlock_locker_v1(PSI_rwlock_locker_state *state, + PSI_rwlock *rwlock, PSI_rwlock_operation op) { PFS_rwlock *pfs_rwlock= reinterpret_cast (rwlock); - DBUG_ASSERT(static_cast (op) >= 0); DBUG_ASSERT(static_cast (op) < array_elements(rwlock_operation_map)); DBUG_ASSERT(pfs_rwlock != NULL); DBUG_ASSERT(pfs_rwlock->m_class != NULL); - if (! flag_events_waits_current) return NULL; if (! pfs_rwlock->m_class->m_enabled) @@ -1218,6 +1272,14 @@ get_thread_rwlock_locker_v1(PSI_rwlock * } PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack [pfs_thread->m_wait_locker_count]; + if (likely(pfs_thread->m_wait_locker_count == 0)) + pfs_locker->m_waits_current.m_nesting_event_id= 0; + else + { + PFS_wait_locker *parent_locker= pfs_locker-1; + pfs_locker->m_waits_current.m_nesting_event_id= + parent_locker->m_waits_current.m_event_id; + } pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS; pfs_locker->m_target.m_rwlock= pfs_rwlock; @@ -1241,7 +1303,8 @@ get_thread_rwlock_locker_v1(PSI_rwlock * } static PSI_cond_locker* -get_thread_cond_locker_v1(PSI_cond *cond, PSI_mutex * /* unused: mutex */, +get_thread_cond_locker_v1(PSI_cond_locker_state *state, + PSI_cond *cond, PSI_mutex * /* unused: mutex */, PSI_cond_operation op) { /* @@ -1276,6 +1339,14 @@ get_thread_cond_locker_v1(PSI_cond *cond } PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack [pfs_thread->m_wait_locker_count]; + if (likely(pfs_thread->m_wait_locker_count == 0)) + pfs_locker->m_waits_current.m_nesting_event_id= 0; + else + { + PFS_wait_locker *parent_locker= pfs_locker-1; + pfs_locker->m_waits_current.m_nesting_event_id= + parent_locker->m_waits_current.m_event_id; + } pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS; pfs_locker->m_target.m_cond= pfs_cond; @@ -1298,14 +1369,29 @@ get_thread_cond_locker_v1(PSI_cond *cond return reinterpret_cast (pfs_locker); } +/** + Implementation of the table instrumentation interface. + @sa PSI_v1::get_thread_table_locker. +*/ static PSI_table_locker* -get_thread_table_locker_v1(PSI_table *table) +get_thread_table_locker_v1(PSI_table_locker_state *state, + PSI_table *table, PSI_table_operation op, ulong flags) { + DBUG_ASSERT(static_cast (op) >= 0); + DBUG_ASSERT(static_cast (op) < array_elements(table_operation_map)); PFS_table *pfs_table= reinterpret_cast (table); DBUG_ASSERT(pfs_table != NULL); DBUG_ASSERT(pfs_table->m_share != NULL); + if (! flag_events_waits_current) return NULL; + if (! global_table_class.m_enabled) + return NULL; + /* + Table locks will be recorded with WL#5371. + */ + if ((op == PSI_TABLE_EXTERNAL_LOCK) || (op == PSI_TABLE_LOCK)) + return NULL; if (! pfs_table->m_share->m_enabled) return NULL; PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); @@ -1320,6 +1406,14 @@ get_thread_table_locker_v1(PSI_table *ta } PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack [pfs_thread->m_wait_locker_count]; + if (likely(pfs_thread->m_wait_locker_count == 0)) + pfs_locker->m_waits_current.m_nesting_event_id= 0; + else + { + PFS_wait_locker *parent_locker= pfs_locker-1; + pfs_locker->m_waits_current.m_nesting_event_id= + parent_locker->m_waits_current.m_event_id; + } pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS; pfs_locker->m_target.m_table= pfs_table; @@ -1334,6 +1428,9 @@ get_thread_table_locker_v1(PSI_table *ta pfs_locker->m_waits_current.m_timer_state= TIMER_STATE_UNTIMED; pfs_locker->m_waits_current.m_object_instance_addr= pfs_table->m_identity; pfs_locker->m_waits_current.m_event_id= pfs_thread->m_event_id++; + pfs_locker->m_waits_current.m_operation= + table_operation_map[static_cast (op)]; + pfs_locker->m_waits_current.m_flags= flags; pfs_locker->m_waits_current.m_wait_class= WAIT_CLASS_TABLE; pfs_thread->m_wait_locker_count++; @@ -1341,7 +1438,8 @@ get_thread_table_locker_v1(PSI_table *ta } static PSI_file_locker* -get_thread_file_name_locker_v1(PSI_file_key key, +get_thread_file_name_locker_v1(PSI_file_locker_state *state, + PSI_file_key key, PSI_file_operation op, const char *name, const void *identity) { @@ -1372,6 +1470,14 @@ get_thread_file_name_locker_v1(PSI_file_ PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack [pfs_thread->m_wait_locker_count]; + if (likely(pfs_thread->m_wait_locker_count == 0)) + pfs_locker->m_waits_current.m_nesting_event_id= 0; + else + { + PFS_wait_locker *parent_locker= pfs_locker-1; + pfs_locker->m_waits_current.m_nesting_event_id= + parent_locker->m_waits_current.m_event_id; + } pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS; pfs_locker->m_target.m_file= pfs_file; @@ -1398,7 +1504,8 @@ get_thread_file_name_locker_v1(PSI_file_ } static PSI_file_locker* -get_thread_file_stream_locker_v1(PSI_file *file, PSI_file_operation op) +get_thread_file_stream_locker_v1(PSI_file_locker_state *state, + PSI_file *file, PSI_file_operation op) { PFS_file *pfs_file= reinterpret_cast (file); @@ -1423,6 +1530,14 @@ get_thread_file_stream_locker_v1(PSI_fil } PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack [pfs_thread->m_wait_locker_count]; + if (likely(pfs_thread->m_wait_locker_count == 0)) + pfs_locker->m_waits_current.m_nesting_event_id= 0; + else + { + PFS_wait_locker *parent_locker= pfs_locker-1; + pfs_locker->m_waits_current.m_nesting_event_id= + parent_locker->m_waits_current.m_event_id; + } pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS; pfs_locker->m_target.m_file= pfs_file; @@ -1449,7 +1564,8 @@ get_thread_file_stream_locker_v1(PSI_fil } static PSI_file_locker* -get_thread_file_descriptor_locker_v1(File file, PSI_file_operation op) +get_thread_file_descriptor_locker_v1(PSI_file_locker_state *state, + File file, PSI_file_operation op) { int index= static_cast (file); @@ -1491,6 +1607,14 @@ get_thread_file_descriptor_locker_v1(Fil } PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack [pfs_thread->m_wait_locker_count]; + if (likely(pfs_thread->m_wait_locker_count == 0)) + pfs_locker->m_waits_current.m_nesting_event_id= 0; + else + { + PFS_wait_locker *parent_locker= pfs_locker-1; + pfs_locker->m_waits_current.m_nesting_event_id= + parent_locker->m_waits_current.m_event_id; + } pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS; pfs_locker->m_target.m_file= pfs_file; @@ -1577,7 +1701,6 @@ get_thread_socket_locker_v1(PSI_socket * return reinterpret_cast (pfs_locker); } -static void unlock_mutex_v1(PSI_thread * thread, PSI_mutex *mutex) { PFS_mutex *pfs_mutex= reinterpret_cast (mutex); DBUG_ASSERT(pfs_mutex != NULL); @@ -1616,7 +1739,7 @@ static void unlock_mutex_v1(PSI_thread * #endif } -static void unlock_rwlock_v1(PSI_thread *thread, PSI_rwlock *rwlock) +static void unlock_rwlock_v1(PSI_rwlock *rwlock) { PFS_rwlock *pfs_rwlock= reinterpret_cast (rwlock); DBUG_ASSERT(pfs_rwlock != NULL); @@ -1692,7 +1815,7 @@ static void unlock_rwlock_v1(PSI_thread #endif } -static void signal_cond_v1(PSI_thread *thread, PSI_cond* cond) +static void signal_cond_v1(PSI_cond* cond) { PFS_cond *pfs_cond= reinterpret_cast (cond); DBUG_ASSERT(pfs_cond != NULL); @@ -1700,7 +1823,7 @@ static void signal_cond_v1(PSI_thread *t pfs_cond->m_cond_stat.m_signal_count++; } -static void broadcast_cond_v1(PSI_thread *thread, PSI_cond* cond) +static void broadcast_cond_v1(PSI_cond* cond) { PFS_cond *pfs_cond= reinterpret_cast (cond); DBUG_ASSERT(pfs_cond != NULL); @@ -1752,7 +1875,7 @@ static void end_mutex_wait_v1(PSI_mutex_ aggregate_single_stat_chain(&mutex->m_wait_stat, wait_time); stat= find_per_thread_mutex_class_wait_stat(wait->m_thread, mutex->m_class); - aggregate_single_stat_chain(stat, wait_time); + aggregate_single_stat_chain(stat, wait_time); } wait->m_thread->m_wait_locker_count--; } @@ -1904,7 +2027,7 @@ static void end_cond_wait_v1(PSI_cond_lo Not thread safe, race conditions will occur. A first race condition is: - thread 1 waits on cond A - - thread 2 waits on cond B + - thread 2 waits on cond A threads 1 and 2 compete when updating the same cond A statistics, possibly missing a min / max / sum / count. A second race condition is: @@ -1927,9 +2050,7 @@ static void end_cond_wait_v1(PSI_cond_lo wait->m_thread->m_wait_locker_count--; } -/** Table operations */ - -static void start_table_wait_v1(PSI_table_locker* locker, +static void start_table_wait_v1(PSI_table_locker* locker, uint index, const char *src_file, uint src_line) { PFS_wait_locker *pfs_locker= reinterpret_cast (locker); @@ -1943,12 +2064,17 @@ static void start_table_wait_v1(PSI_tabl } wait->m_source_file= src_file; wait->m_source_line= src_line; - wait->m_operation= OPERATION_TYPE_LOCK; PFS_table_share *share= pfs_locker->m_target.m_table->m_share; + wait->m_object_type= share->get_object_type(); wait->m_schema_name= share->m_schema_name; wait->m_schema_name_length= share->m_schema_name_length; wait->m_object_name= share->m_table_name; wait->m_object_name_length= share->m_table_name_length; + /* FIXME: revise this */ + if (share->get_object_type() == OBJECT_TYPE_TEMPORARY_TABLE) + wait->m_index= MAX_KEY; + else + wait->m_index= index; } static void end_table_wait_v1(PSI_table_locker* locker) @@ -1967,10 +2093,6 @@ static void end_table_wait_v1(PSI_table_ if (flag_events_waits_history_long) insert_events_waits_history_long(wait); - PFS_table *table= pfs_locker->m_target.m_table; - ulonglong wait_time= wait->m_timer_end - wait->m_timer_start; - aggregate_single_stat_chain(&table->m_wait_stat, wait_time); - /* There is currently no per table and per thread aggregation. The number of tables in the application is arbitrary, and may be high. @@ -1995,7 +2117,6 @@ static void start_file_wait_v1(PSI_file_ static void end_file_wait_v1(PSI_file_locker *locker, size_t count); - static PSI_file* start_file_open_wait_v1(PSI_file_locker *locker, const char *src_file, uint src_line) @@ -2269,6 +2390,7 @@ PSI_v1 PFS_v1= destroy_socket_v1, get_table_share_v1, release_table_share_v1, + drop_table_share_v1, open_table_v1, close_table_v1, create_file_v1, === modified file 'storage/perfschema/pfs_column_types.h' --- a/storage/perfschema/pfs_column_types.h 2010-06-22 23:15:38 +0000 +++ b/storage/perfschema/pfs_column_types.h 2010-08-03 21:14:19 +0000 @@ -111,20 +111,36 @@ enum enum_operation_type OPERATION_TYPE_FILERENAME= 24, OPERATION_TYPE_FILESYNC= 25, - OPERATION_TYPE_SOCKETCREATE = 26, - OPERATION_TYPE_SOCKETCONNECT = 27, - OPERATION_TYPE_SOCKETBIND = 28, - OPERATION_TYPE_SOCKETCLOSE = 29, - OPERATION_TYPE_SOCKETSEND = 30, - OPERATION_TYPE_SOCKETRECV = 31, - OPERATION_TYPE_SOCKETSEEK = 32, - OPERATION_TYPE_SOCKETOPT = 33, - OPERATION_TYPE_SOCKETSTAT = 34, - OPERATION_TYPE_SOCKETSHUTDOWN = 35 + OPERATION_TYPE_TABLE_LOCK= 26, + OPERATION_TYPE_TABLE_EXTERNAL_LOCK= 27, + OPERATION_TYPE_TABLE_FETCH= 28, + OPERATION_TYPE_TABLE_WRITE_ROW= 29, + OPERATION_TYPE_TABLE_UPDATE_ROW= 30, + OPERATION_TYPE_TABLE_DELETE_ROW= 31, + + OPERATION_TYPE_SOCKETCREATE = 32, + OPERATION_TYPE_SOCKETCONNECT = 33, + OPERATION_TYPE_SOCKETBIND = 34, + OPERATION_TYPE_SOCKETCLOSE = 35, + OPERATION_TYPE_SOCKETSEND = 36, + OPERATION_TYPE_SOCKETRECV = 37, + OPERATION_TYPE_SOCKETSEEK = 38, + OPERATION_TYPE_SOCKETOPT = 39, + OPERATION_TYPE_SOCKETSTAT = 40, + OPERATION_TYPE_SOCKETSHUTDOWN = 41 }; #define FIRST_OPERATION_TYPE (static_cast (OPERATION_TYPE_LOCK)) -#define LAST_OPERATION_TYPE (static_cast (OPERATION_TYPE_FILESYNC)) +#define LAST_OPERATION_TYPE (static_cast (OPERATION_TYPE_SOCKETSHUTDOWN) #define COUNT_OPERATION_TYPE (LAST_OPERATION_TYPE - FIRST_OPERATION_TYPE + 1) +enum enum_object_type +{ + OBJECT_TYPE_TABLE= 1, + OBJECT_TYPE_TEMPORARY_TABLE= 2 +}; +#define FIRST_OBJECT_TYPE (static_cast (OBJECT_TYPE_TABLE)) +#define LAST_OBJECT_TYPE (static_cast (OBJECT_TYPE_TEMPORARY_TABLE)) +#define COUNT_OBJECT_TYPE (LAST_OBJECT_TYPE - FIRST_OBJECT_TYPE + 1) + #endif === modified file 'storage/perfschema/pfs_events_waits.h' --- a/storage/perfschema/pfs_events_waits.h 2010-07-09 02:23:31 +0000 +++ b/storage/perfschema/pfs_events_waits.h 2010-08-03 21:14:19 +0000 @@ -110,6 +110,8 @@ struct PFS_events_waits enum timer_state m_timer_state; /** Event id. */ ulonglong m_event_id; + /** Nesting event id. */ + ulonglong m_nesting_event_id; /** Timer start. This member is populated only if m_timed is true. @@ -124,6 +126,8 @@ struct PFS_events_waits const char *m_schema_name; /** Length in bytes of @c m_schema_name. */ uint m_schema_name_length; + /** Object type */ + enum_object_type m_object_type; /** Object name. */ const char *m_object_name; /** Length in bytes of @c m_object_name. */ @@ -141,6 +145,13 @@ struct PFS_events_waits This member is populated for file READ/WRITE operations only. */ size_t m_number_of_bytes; + /** + Index used. + This member is populated for TABLE IO operations only. + */ + uint m_index; + /** Flags */ + ulong m_flags; }; /** === modified file 'storage/perfschema/pfs_instr.cc' --- a/storage/perfschema/pfs_instr.cc 2010-07-09 02:23:31 +0000 +++ b/storage/perfschema/pfs_instr.cc 2010-08-03 21:14:19 +0000 @@ -1049,10 +1049,12 @@ void destroy_file(PFS_thread *thread, PF /** Create instrumentation for a table instance. @param share the table share + @param opening_thread the opening thread @param identity the table address @return a table instance, or NULL */ -PFS_table* create_table(PFS_table_share *share, const void *identity) +PFS_table* create_table(PFS_table_share *share, PFS_thread *opening_thread, + const void *identity) { PFS_scan scan; uint random= randomized_index(identity, table_max); @@ -1071,10 +1073,12 @@ PFS_table* create_table(PFS_table_share { pfs->m_identity= identity; pfs->m_share= share; + share->m_refcount++; pfs->m_wait_stat.m_control_flag= &flag_events_waits_summary_by_instance; pfs->m_wait_stat.m_parent= &share->m_wait_stat; reset_single_stat_link(&pfs->m_wait_stat); + pfs->m_opening_thread= opening_thread; pfs->m_lock.dirty_to_allocated(); return pfs; } === modified file 'storage/perfschema/pfs_instr.h' --- a/storage/perfschema/pfs_instr.h 2010-07-29 19:56:17 +0000 +++ b/storage/perfschema/pfs_instr.h 2010-08-03 21:14:19 +0000 @@ -123,6 +123,8 @@ struct PFS_file : public PFS_instr /** Instrumented table implementation. @see PSI_table. */ struct PFS_table : public PFS_instr { + /** Owner. */ + PFS_thread *m_opening_thread; /** Table share. */ PFS_table_share *m_share; /** Table identity, typically a handler. */ @@ -289,7 +291,8 @@ PFS_file* find_or_create_file(PFS_thread const char *filename, uint len); void release_file(PFS_file *pfs); void destroy_file(PFS_thread *thread, PFS_file *pfs); -PFS_table* create_table(PFS_table_share *share, const void *identity); +PFS_table* create_table(PFS_table_share *share, PFS_thread *opening_thread, + const void *identity); void destroy_table(PFS_table *pfs); PFS_socket* create_socket(PFS_socket_class *socket_class, const void *identity); === modified file 'storage/perfschema/pfs_instr_class.cc' --- a/storage/perfschema/pfs_instr_class.cc 2010-07-07 19:49:15 +0000 +++ b/storage/perfschema/pfs_instr_class.cc 2010-08-03 21:14:19 +0000 @@ -20,6 +20,8 @@ #include "my_global.h" #include "my_sys.h" +#include "structs.h" +#include "table.h" #include "pfs_instr_class.h" #include "pfs_instr.h" #include "pfs_global.h" @@ -110,15 +112,24 @@ PFS_table_share *table_share_array= NULL PFS_instr_class global_table_class= { - "wait/table", /* name */ - 10, /* name length */ + "wait/io/table/sql/handler", /* name */ + 25, /* name length */ 0, /* flags */ true, /* enabled */ true, /* timed */ { &flag_events_waits_current, NULL, 0, 0, 0, 0} /* wait stat chain */ }; -/** Hash table for instrumented tables. */ +/** + Hash index for instrumented table shares. + This index is searched by table fully qualified name (@c PFS_table_share_key), + and points to instrumented table shares (@c PFS_table_share). + @sa table_share_array + @sa PFS_table_share_key + @sa PFS_table_share + @sa table_share_hash_get_key + @sa get_table_share_hash_pins +*/ static LF_HASH table_share_hash; /** True if table_share_hash is initialized. */ static bool table_share_hash_inited= false; @@ -268,6 +279,9 @@ void cleanup_table_share(void) table_share_max= 0; } +/** + get_key function for @c table_share_hash. +*/ static uchar *table_share_hash_get_key(const uchar *entry, size_t *length, my_bool) { @@ -306,6 +320,51 @@ void cleanup_table_share_hash(void) } /** + Get the hash pins for @table_share_hash. + @param thread The running thread. + @returns The LF_HASH pins for the thread. +*/ +LF_PINS* get_table_share_hash_pins(PFS_thread *thread) +{ + if (! table_share_hash_inited) + return NULL; + if (unlikely(thread->m_table_share_hash_pins == NULL)) + thread->m_table_share_hash_pins= lf_hash_get_pins(&table_share_hash); + return thread->m_table_share_hash_pins; +} + +/** + Set a table share hash key. + @param [out] key The key to polulate. + @param temporary True for TEMPORARY TABLE. + @param schema_name The table schema name. + @param schema_name_length The table schema name length. + @param table_name The table name. + @param table_name_length The table name length. +*/ +static void set_table_share_key(PFS_table_share_key *key, + bool temporary, + const char *schema_name, uint schema_name_length, + const char *table_name, uint table_name_length) +{ + DBUG_ASSERT(schema_name_length <= NAME_LEN); + DBUG_ASSERT(table_name_length <= NAME_LEN); + + char *ptr= &key->m_hash_key[0]; + ptr[0]= (temporary ? OBJECT_TYPE_TEMPORARY_TABLE : OBJECT_TYPE_TABLE); + ptr++; + memcpy(ptr, schema_name, schema_name_length); + ptr+= schema_name_length; + ptr[0]= 0; + ptr++; + memcpy(ptr, table_name, table_name_length); + ptr+= table_name_length; + ptr[0]= 0; + ptr++; + key->m_key_length= ptr - &key->m_hash_key[0]; +} + +/** Initialize the file class buffer. @param file_class_sizing max number of file class @return 0 on success @@ -797,68 +856,69 @@ PFS_socket_class *sanitize_socket_class( } /** - Find or create a table instance by name. + Find or create a table share instrumentation. @param thread the executing instrumented thread - @param schema_name the table schema name - @param schema_name_length the table schema name length - @param table_name the table name - @param table_name_length the table name length - @return a table instance, or NULL + @param temporary true for TEMPORARY TABLE + @param share table share + @return a table share, or NULL */ PFS_table_share* find_or_create_table_share(PFS_thread *thread, - const char *schema_name, - uint schema_name_length, - const char *table_name, - uint table_name_length) + bool temporary, + const TABLE_SHARE *share) { /* See comments in register_mutex_class */ int pass; PFS_table_share_key key; - if (! table_share_hash_inited) + LF_PINS *pins= get_table_share_hash_pins(thread); + if (unlikely(pins == NULL)) { - /* Table instrumentation can be turned off. */ table_share_lost++; return NULL; } - if (unlikely(thread->m_table_share_hash_pins == NULL)) - { - thread->m_table_share_hash_pins= lf_hash_get_pins(&table_share_hash); - if (unlikely(thread->m_table_share_hash_pins == NULL)) - { - table_share_lost++; - return NULL; - } - } - - DBUG_ASSERT(schema_name_length <= NAME_LEN); - DBUG_ASSERT(table_name_length <= NAME_LEN); - - char *ptr= &key.m_hash_key[0]; - memcpy(ptr, schema_name, schema_name_length); - ptr+= schema_name_length; - ptr[0]= 0; ptr++; - memcpy(ptr, table_name, table_name_length); - ptr+= table_name_length; - ptr[0]= 0; ptr++; - key.m_key_length= ptr - &key.m_hash_key[0]; + const char *schema_name= share->db.str; + uint schema_name_length= share->db.length; + const char *table_name= share->table_name.str; + uint table_name_length= share->table_name.length; + + set_table_share_key(&key, temporary, + schema_name, schema_name_length, + table_name, table_name_length); PFS_table_share **entry; uint retry_count= 0; const uint retry_max= 3; + bool enabled= true; + bool timed= true; + search: entry= reinterpret_cast - (lf_hash_search(&table_share_hash, thread->m_table_share_hash_pins, - &key.m_hash_key[0], key.m_key_length)); + (lf_hash_search(&table_share_hash, pins, + key.m_hash_key, key.m_key_length)); if (entry && (entry != MY_ERRPTR)) { PFS_table_share *pfs; pfs= *entry; - lf_hash_search_unpin(thread->m_table_share_hash_pins); + pfs->m_refcount++ ; + lf_hash_search_unpin(pins); return pfs; } + if (retry_count == 0) + { + /* No per object lokup yet */ + enabled= global_table_class.m_enabled; + timed= global_table_class.m_timed; + + /* + Even when enabled is false, a record is added in the dictionary: + - It makes enabling a table already in the table cache possible, + - It improves performances for the next time a TABLE_SHARE is reloaded + in the table cache. + */ + } + /* table_name is not constant, just using it for noise on create */ uint i= randomized_index(table_name, table_share_max); @@ -877,21 +937,20 @@ search: if (pfs->m_lock.free_to_dirty()) { pfs->m_key= key; - pfs->m_schema_name= &pfs->m_key.m_hash_key[0]; + pfs->m_schema_name= &pfs->m_key.m_hash_key[1]; pfs->m_schema_name_length= schema_name_length; - pfs->m_table_name= &pfs->m_key.m_hash_key[schema_name_length + 1]; + pfs->m_table_name= &pfs->m_key.m_hash_key[schema_name_length + 2]; pfs->m_table_name_length= table_name_length; pfs->m_wait_stat.m_control_flag= &flag_events_waits_summary_by_instance; pfs->m_wait_stat.m_parent= NULL; reset_single_stat_link(&pfs->m_wait_stat); - pfs->m_enabled= true; - pfs->m_timed= true; - pfs->m_aggregated= false; + pfs->m_enabled= enabled; + pfs->m_timed= timed; + pfs->m_refcount= 1; int res; - res= lf_hash_insert(&table_share_hash, - thread->m_table_share_hash_pins, &pfs); + res= lf_hash_insert(&table_share_hash, pins, &pfs); if (likely(res == 0)) { pfs->m_lock.dirty_to_allocated(); @@ -924,6 +983,63 @@ search: return NULL; } +/** + Purge an instrumented table share from the performance schema buffers. + The table share is removed from the hash index, and freed. + @param thread The running thread + @param pfs The table share to purge +*/ +void purge_table_share(PFS_thread *thread, PFS_table_share *pfs) +{ + if (pfs->m_refcount == 1) + { + LF_PINS* pins= get_table_share_hash_pins(thread); + if (likely(pins != NULL)) + lf_hash_delete(&table_share_hash, pins, + pfs->m_key.m_hash_key, pfs->m_key.m_key_length); + pfs->m_lock.allocated_to_free(); + } +} + +/** + Drop the instrumented table share associated with a table. + @param thread The running thread + @param temporary True for TEMPORARY TABLE + @param schema_name The table schema name + @param schema_name_length The table schema name length + @param table_name The table name + @parem table_name_length The table name length +*/ +void drop_table_share(PFS_thread *thread, + bool temporary, + const char *schema_name, uint schema_name_length, + const char *table_name, uint table_name_length) +{ + PFS_table_share_key key; + LF_PINS* pins= get_table_share_hash_pins(thread); + if (unlikely(pins == NULL)) + return; + set_table_share_key(&key, temporary, schema_name, schema_name_length, + table_name, table_name_length); + PFS_table_share **entry; + entry= reinterpret_cast + (lf_hash_search(&table_share_hash, pins, + key.m_hash_key, key.m_key_length)); + if (entry && (entry != MY_ERRPTR)) + { + PFS_table_share *pfs= *entry; + lf_hash_search_unpin(pins); + lf_hash_delete(&table_share_hash, pins, + pfs->m_key.m_hash_key, pfs->m_key.m_key_length); + pfs->m_lock.allocated_to_free(); + } +} + +/** + Sanitize an unsafe table_share pointer. + @param unsafe The possibly corrupt pointer. + @return A valid table_safe_pointer, or NULL. +*/ PFS_table_share *sanitize_table_share(PFS_table_share *unsafe) { SANITIZE_ARRAY_BODY(table_share_array, table_share_max, unsafe); === modified file 'storage/perfschema/pfs_instr_class.h' --- a/storage/perfschema/pfs_instr_class.h 2010-06-22 23:15:38 +0000 +++ b/storage/perfschema/pfs_instr_class.h 2010-08-03 21:14:19 +0000 @@ -42,6 +42,7 @@ #include #include "pfs_lock.h" #include "pfs_stat.h" +#include "pfs_column_types.h" /** @addtogroup Performance_schema_buffers @@ -136,10 +137,10 @@ struct PFS_table_share_key /** Hash search key. This has to be a string for LF_HASH, - the format is "<0x00><0x00>" + the format is "<0x00><0x00>" @see create_table_def_key */ - char m_hash_key[NAME_LEN + 1 + NAME_LEN + 1]; + char m_hash_key[1 + NAME_LEN + 1 + NAME_LEN + 1]; /** Length in bytes of @c m_hash_key. */ uint m_key_length; }; @@ -147,6 +148,11 @@ struct PFS_table_share_key /** Instrumentation metadata for a table share. */ struct PFS_table_share { + enum_object_type get_object_type() + { + return (enum_object_type) m_key.m_hash_key[0]; + } + /** Internal lock. */ pfs_lock m_lock; /** Search key. */ @@ -165,8 +171,9 @@ struct PFS_table_share bool m_enabled; /** True if this table instrument is timed. */ bool m_timed; - /** True if this table instrument is aggregated. */ - bool m_aggregated; + bool m_purge; + /** Number of opened table handles. */ + uint m_refcount; }; /** @@ -241,10 +248,13 @@ PFS_socket_class *find_socket_class(PSI_ PFS_socket_class *sanitize_socket_class(PFS_socket_class *unsafe); PFS_table_share *find_or_create_table_share(PFS_thread *thread, - const char *schema_name, - uint schema_name_length, - const char *table_name, - uint table_name_length); + bool temporary, + const TABLE_SHARE *share); +void purge_table_share(PFS_thread *thread, PFS_table_share *pfs); +void drop_table_share(PFS_thread *thread, + bool temporary, + const char *schema_name, uint schema_name_length, + const char *table_name, uint table_name_length); PFS_table_share *sanitize_table_share(PFS_table_share *unsafe); === modified file 'storage/perfschema/pfs_server.h' --- a/storage/perfschema/pfs_server.h 2010-07-07 19:49:15 +0000 +++ b/storage/perfschema/pfs_server.h 2010-08-03 21:14:19 +0000 @@ -61,10 +61,10 @@ #define PFS_MAX_SOCKET_CLASS 50 #endif #ifndef PFS_MAX_TABLE_SHARE - #define PFS_MAX_TABLE_SHARE 50000 + #define PFS_MAX_TABLE_SHARE 1000 #endif #ifndef PFS_MAX_TABLE - #define PFS_MAX_TABLE 100000 + #define PFS_MAX_TABLE 10000 #endif #ifndef PFS_WAITS_HISTORY_SIZE #define PFS_WAITS_HISTORY_SIZE 10 @@ -73,6 +73,7 @@ #define PFS_WAITS_HISTORY_LONG_SIZE 10000 #endif +/** Performance schema global sizing parameters. */ struct PFS_global_param { bool m_enabled; @@ -80,12 +81,20 @@ struct PFS_global_param ulong m_rwlock_class_sizing; ulong m_cond_class_sizing; ulong m_thread_class_sizing; + /** + Maximum number of instrumented table share. + @sa table_share_lost. + */ ulong m_table_share_sizing; ulong m_file_class_sizing; ulong m_mutex_sizing; ulong m_rwlock_sizing; ulong m_cond_sizing; ulong m_thread_sizing; + /** + Maximum number of instrumented table handles. + @sa table_lost. + */ ulong m_table_sizing; ulong m_file_sizing; ulong m_file_handle_sizing; === modified file 'storage/perfschema/table_all_instr.h' --- a/storage/perfschema/table_all_instr.h 2010-07-09 02:23:31 +0000 +++ b/storage/perfschema/table_all_instr.h 2010-08-03 21:14:19 +0000 @@ -24,6 +24,7 @@ #include "pfs_instr_class.h" #include "pfs_instr.h" #include "pfs_engine_table.h" +#include "table_helper.h" /** @addtogroup Performance_schema_tables === modified file 'storage/perfschema/table_events_waits.cc' --- a/storage/perfschema/table_events_waits.cc 2010-06-03 13:30:54 +0000 +++ b/storage/perfschema/table_events_waits.cc 2010-08-03 21:14:19 +0000 @@ -231,6 +231,7 @@ void table_events_waits_common::make_row m_row.m_thread_internal_id= safe_thread->m_thread_internal_id; m_row.m_event_id= wait->m_event_id; + m_row.m_nesting_event_id= wait->m_nesting_event_id; m_row.m_timer_state= wait->m_timer_state; m_row.m_timer_start= wait->m_timer_start; m_row.m_timer_end= wait->m_timer_end; @@ -257,8 +258,16 @@ void table_events_waits_common::make_row safe_class= sanitize_cond_class((PFS_cond_class*) wait->m_class); break; case WAIT_CLASS_TABLE: - m_row.m_object_type= "TABLE"; - m_row.m_object_type_length= 5; + if (wait->m_object_type == OBJECT_TYPE_TABLE) + { + m_row.m_object_type= "TABLE"; + m_row.m_object_type_length= 5; + } + else + { + m_row.m_object_type= "TEMPORARY TABLE"; + m_row.m_object_type_length= 15; + } memcpy(m_row.m_object_schema, wait->m_schema_name, wait->m_schema_name_length); m_row.m_object_schema_length= wait->m_schema_name_length; @@ -300,7 +309,7 @@ void table_events_waits_common::make_row m_row.m_source_length= sizeof(m_row.m_source); m_row.m_operation= wait->m_operation; m_row.m_number_of_bytes= wait->m_number_of_bytes; - m_row.m_flags= 0; + m_row.m_flags= wait->m_flags; if (thread_own_wait) { @@ -361,7 +370,15 @@ static const LEX_STRING operation_names_ { C_STRING_WITH_LEN("chsize") }, { C_STRING_WITH_LEN("delete") }, { C_STRING_WITH_LEN("rename") }, - { C_STRING_WITH_LEN("sync") } + { C_STRING_WITH_LEN("sync") }, + + /* Table operations */ + { C_STRING_WITH_LEN("lock") }, + { C_STRING_WITH_LEN("external lock") }, + { C_STRING_WITH_LEN("fetch") }, + { C_STRING_WITH_LEN("insert") }, /* write row */ + { C_STRING_WITH_LEN("update") }, /* update row */ + { C_STRING_WITH_LEN("delete") } /* delete row */ }; @@ -463,7 +480,7 @@ int table_events_waits_common::read_row_ set_field_ulonglong(f, m_row.m_object_instance_addr); break; case 12: /* NESTING_EVENT_ID */ - f->set_null(); + set_field_ulonglong(f, m_row.m_nesting_event_id); break; case 13: /* OPERATION */ operation= &operation_names_map[(int) m_row.m_operation - 1]; @@ -478,7 +495,11 @@ int table_events_waits_common::read_row_ f->set_null(); break; case 15: /* FLAGS */ - set_field_ulong(f, m_row.m_flags); + if ((m_row.m_operation == OPERATION_TYPE_TABLE_LOCK) || + (m_row.m_operation == OPERATION_TYPE_TABLE_EXTERNAL_LOCK)) + set_field_ulong(f, m_row.m_flags); + else + f->set_null(); break; default: DBUG_ASSERT(false); @@ -525,14 +546,26 @@ int table_events_waits_current::rnd_next We do not show nested events for now, this will be revised with TABLE io */ -#define ONLY_SHOW_ONE_WAIT +// #define ONLY_SHOW_ONE_WAIT #ifdef ONLY_SHOW_ONE_WAIT if (m_pos.m_index_2 >= 1) continue; #else - if (m_pos.m_index_2 >= pfs_thread->m_wait_locker_count) - continue; + uint safe_locker_count= pfs_thread->m_wait_locker_count; + + if (safe_locker_count == 0) + { + /* Display the last top level wait, when completed */ + if (m_pos.m_index_2 >= 1) + continue; + } + else + { + /* Display all pending waits, when in progress */ + if (m_pos.m_index_2 >= safe_locker_count) + continue; + } #endif wait= &pfs_thread->m_wait_locker_stack[m_pos.m_index_2].m_waits_current; @@ -567,9 +600,24 @@ int table_events_waits_current::rnd_pos( if (! pfs_thread->m_lock.is_populated()) return HA_ERR_RECORD_DELETED; -#ifdef ONLY_SHOW_CURRENT_WAITS - if (m_pos.m_index_2 >= pfs_thread->m_wait_locker_count) +#ifdef ONLY_SHOW_ONE_WAIT + if (m_pos.m_index_2 >= 1) return HA_ERR_RECORD_DELETED; +#else + uint safe_locker_count= pfs_thread->m_wait_locker_count; + + if (safe_locker_count == 0) + { + /* Display the last top level wait, when completed */ + if (m_pos.m_index_2 >= 1) + return HA_ERR_RECORD_DELETED; + } + else + { + /* Display all pending waits, when in progress */ + if (m_pos.m_index_2 >= safe_locker_count) + return HA_ERR_RECORD_DELETED; + } #endif DBUG_ASSERT(m_pos.m_index_2 < LOCKER_STACK_SIZE); === modified file 'storage/perfschema/table_events_waits.h' --- a/storage/perfschema/table_events_waits.h 2010-06-03 13:30:54 +0000 +++ b/storage/perfschema/table_events_waits.h 2010-08-03 21:14:19 +0000 @@ -39,6 +39,8 @@ struct row_events_waits ulong m_thread_internal_id; /** Column EVENT_ID. */ ulonglong m_event_id; + /** Column NESTING_EVENT_ID. */ + ulonglong m_nesting_event_id; /** Column EVENT_NAME. */ const char *m_name; /** Length in bytes of @c m_name. */ === modified file 'storage/perfschema/table_events_waits_summary.h' --- a/storage/perfschema/table_events_waits_summary.h 2010-07-09 02:23:31 +0000 +++ b/storage/perfschema/table_events_waits_summary.h 2010-08-03 21:14:19 +0000 @@ -26,6 +26,7 @@ #include "pfs_instr_class.h" #include "pfs_instr.h" #include "table_all_instr.h" +#include "table_helper.h" /** @addtogroup Performance_schema_tables === modified file 'storage/perfschema/table_setup_instruments.cc' --- a/storage/perfschema/table_setup_instruments.cc 2010-07-07 19:49:15 +0000 +++ b/storage/perfschema/table_setup_instruments.cc 2010-08-03 21:14:19 +0000 @@ -143,6 +143,14 @@ int table_setup_instruments::rnd_next(vo return 0; } break; + case pos_setup_instruments::VIEW_TABLE: + if (m_pos.m_index_2 == 1) + { + make_row(&global_table_class); + m_next_pos.set_after(&m_pos); + return 0; + } + break; } } @@ -203,6 +211,13 @@ int table_setup_instruments::rnd_pos(con return 0; } break; + case pos_setup_instruments::VIEW_TABLE: + if (m_pos.m_index_2 == 1) + { + make_row(&global_table_class); + return 0; + } + break; } return HA_ERR_RECORD_DELETED; === modified file 'storage/perfschema/table_setup_instruments.h' --- a/storage/perfschema/table_setup_instruments.h 2010-07-09 02:23:31 +0000 +++ b/storage/perfschema/table_setup_instruments.h 2010-08-03 21:14:19 +0000 @@ -52,8 +52,9 @@ struct pos_setup_instruments : public PF /** Reverved for WL#4674, PERFORMANCE_SCHEMA Setup For Actors. */ static const uint VIEW_THREAD= 4; static const uint VIEW_FILE= 5; - static const uint VIEW_SOCKET= 6; - static const uint LAST_VIEW= 6; + static const uint VIEW_TABLE= 6 ; + static const uint VIEW_SOCKET= 7; + static const uint LAST_VIEW= 8; pos_setup_instruments() : PFS_double_index(FIRST_VIEW, 1) === modified file 'storage/perfschema/table_setup_objects.cc' --- a/storage/perfschema/table_setup_objects.cc 2010-06-03 13:30:54 +0000 +++ b/storage/perfschema/table_setup_objects.cc 2010-08-03 21:14:19 +0000 @@ -112,59 +112,11 @@ void table_setup_objects::reset_position int table_setup_objects::rnd_next(void) { - PFS_table_share *table_share; - - for (m_pos.set_at(&m_next_pos); - m_pos.has_more_view(); - m_pos.next_view()) - { - switch (m_pos.m_index_1) { - case pos_setup_objects::VIEW_TABLE: - for ( ; m_pos.m_index_2 < table_share_max; m_pos.m_index_2++) - { - table_share= &table_share_array[m_pos.m_index_2]; - if (table_share->m_lock.is_populated()) - { - make_row(table_share); - m_next_pos.set_after(&m_pos); - return 0; - } - } - break; - case pos_setup_objects::VIEW_EVENT: - case pos_setup_objects::VIEW_PROCEDURE: - case pos_setup_objects::VIEW_FUNCTION: - default: - break; - } - } - return HA_ERR_END_OF_FILE; } int table_setup_objects::rnd_pos(const void *pos) { - PFS_table_share *share; - - set_position(pos); - - switch (m_pos.m_index_1) { - case pos_setup_objects::VIEW_TABLE: - DBUG_ASSERT(m_pos.m_index_2 < table_share_max); - share= &table_share_array[m_pos.m_index_2]; - if (share->m_lock.is_populated()) - { - make_row(share); - return 0; - } - break; - case pos_setup_objects::VIEW_EVENT: - case pos_setup_objects::VIEW_PROCEDURE: - case pos_setup_objects::VIEW_FUNCTION: - default: - break; - } - return HA_ERR_RECORD_DELETED; } @@ -184,7 +136,7 @@ void table_setup_objects::make_row(PFS_t m_row.m_object_name_length= share->m_table_name_length; m_row.m_enabled_ptr= &share->m_enabled; m_row.m_timed_ptr= &share->m_timed; - m_row.m_aggregated_ptr= &share->m_aggregated; + m_row.m_aggregated_ptr= NULL; if (share->m_lock.end_optimistic_lock(&lock)) m_row_exists= true; === modified file 'storage/perfschema/table_setup_objects.h' --- a/storage/perfschema/table_setup_objects.h 2010-06-03 13:30:54 +0000 +++ b/storage/perfschema/table_setup_objects.h 2010-08-03 21:14:19 +0000 @@ -23,6 +23,7 @@ #include "pfs_instr_class.h" #include "pfs_engine_table.h" +#include "table_helper.h" /** @addtogroup Performance_schema_tables @@ -53,17 +54,17 @@ struct pos_setup_objects : public PFS_do public PFS_object_view_constants { pos_setup_objects() - : PFS_double_index(VIEW_TABLE, 0) + : PFS_double_index(FIRST_VIEW, 0) {} inline void reset(void) { - m_index_1= VIEW_TABLE; + m_index_1= FIRST_VIEW; m_index_2= 0; } inline bool has_more_view(void) - { return (m_index_1 <= VIEW_FUNCTION); } + { return (m_index_1 <= LAST_VIEW); } inline void next_view(void) { --===============5683958773542774944== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/chris.powers@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: chris.powers@stripped # target_branch: file:///home/cpowers/work/dev/base-wl4896/mysql/ # testament_sha1: f53b915465edae5b60e07014aea8718c473a7463 # timestamp: 2010-08-03 16:14:25 -0500 # source_branch: bzr+ssh://cpowers@stripped/bzrroot\ # /server/mysql-next-mr/ # base_revision_id: chris.powers@stripped\ # 043jpyctutwrrss6 # # Begin bundle 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 YLgINUbFA6Cn/F3JFOFCQVaAVqA= --===============5683958773542774944==--