3348 Marc Alff 2011-05-06
WL#5378 PERFORMANCE SCHEMA SUMMARY BY USER / HOST
Part 1 (Implementation only)
added:
storage/perfschema/cursor_by_account.cc
storage/perfschema/cursor_by_account.h
storage/perfschema/cursor_by_host.cc
storage/perfschema/cursor_by_host.h
storage/perfschema/cursor_by_thread.cc
storage/perfschema/cursor_by_thread.h
storage/perfschema/cursor_by_user.cc
storage/perfschema/cursor_by_user.h
storage/perfschema/pfs_account.cc
storage/perfschema/pfs_account.h
storage/perfschema/pfs_host.cc
storage/perfschema/pfs_host.h
storage/perfschema/pfs_user.cc
storage/perfschema/pfs_user.h
storage/perfschema/table_accounts.cc
storage/perfschema/table_accounts.h
storage/perfschema/table_esgs_by_account_by_event_name.cc
storage/perfschema/table_esgs_by_account_by_event_name.h
storage/perfschema/table_esgs_by_host_by_event_name.cc
storage/perfschema/table_esgs_by_host_by_event_name.h
storage/perfschema/table_esgs_by_user_by_event_name.cc
storage/perfschema/table_esgs_by_user_by_event_name.h
storage/perfschema/table_esms_by_account_by_event_name.cc
storage/perfschema/table_esms_by_account_by_event_name.h
storage/perfschema/table_esms_by_host_by_event_name.cc
storage/perfschema/table_esms_by_host_by_event_name.h
storage/perfschema/table_esms_by_user_by_event_name.cc
storage/perfschema/table_esms_by_user_by_event_name.h
storage/perfschema/table_ews_by_account_by_event_name.cc
storage/perfschema/table_ews_by_account_by_event_name.h
storage/perfschema/table_ews_by_host_by_event_name.cc
storage/perfschema/table_ews_by_host_by_event_name.h
storage/perfschema/table_ews_by_user_by_event_name.cc
storage/perfschema/table_ews_by_user_by_event_name.h
storage/perfschema/table_hosts.cc
storage/perfschema/table_hosts.h
storage/perfschema/table_users.cc
storage/perfschema/table_users.h
modified:
scripts/mysql_system_tables.sql
sql/sys_vars.cc
storage/perfschema/CMakeLists.txt
storage/perfschema/ha_perfschema.cc
storage/perfschema/pfs.cc
storage/perfschema/pfs_engine_table.cc
storage/perfschema/pfs_events_stages.cc
storage/perfschema/pfs_events_stages.h
storage/perfschema/pfs_events_statements.cc
storage/perfschema/pfs_events_statements.h
storage/perfschema/pfs_events_waits.cc
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.cc
storage/perfschema/pfs_server.h
storage/perfschema/pfs_setup_actor.cc
storage/perfschema/pfs_setup_object.cc
storage/perfschema/pfs_stat.h
storage/perfschema/pfs_visitor.cc
storage/perfschema/pfs_visitor.h
storage/perfschema/table_esgs_global_by_event_name.cc
storage/perfschema/table_esms_global_by_event_name.cc
storage/perfschema/table_helper.cc
storage/perfschema/table_helper.h
storage/perfschema/table_threads.cc
storage/perfschema/table_threads.h
3347 Davi Arnaut 2011-04-29 [merge]
Merge of mysql-5.5 into mysql-trunk.
modified:
config.h.cmake
configure.cmake
vio/viosocket.c
=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql 2011-03-18 22:51:17 +0000
+++ b/scripts/mysql_system_tables.sql 2011-05-07 00:40:25 +0000
@@ -293,6 +293,64 @@ EXECUTE stmt;
DROP PREPARE stmt;
--
+-- TABLE EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_waits_summary_by_host_by_event_name("
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_waits_summary_by_user_by_event_name("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_waits_summary_by_account_by_event_name("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
-- TABLE EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME
--
@@ -815,6 +873,64 @@ EXECUTE stmt;
DROP PREPARE stmt;
--
+-- TABLE EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_stages_summary_by_host_by_event_name("
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_stages_summary_by_user_by_event_name("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_stages_summary_by_account_by_event_name("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
-- TABLE EVENTS_STAGES_SUMMARY_GLOBAL_BY_EVENT_NAME
--
@@ -1018,6 +1134,121 @@ EXECUTE stmt;
DROP PREPARE stmt;
--
+-- TABLE EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_statements_summary_by_host_by_event_name("
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null,"
+ "SUM_LOCK_TIME BIGINT unsigned not null,"
+ "SUM_ERRORS BIGINT unsigned not null,"
+ "SUM_WARNINGS BIGINT unsigned not null,"
+ "SUM_ROWS_AFFECTED BIGINT unsigned not null,"
+ "SUM_ROWS_SENT BIGINT unsigned not null,"
+ "SUM_ROWS_EXAMINED BIGINT unsigned not null,"
+ "SUM_CREATED_TMP_DISK_TABLES BIGINT unsigned not null,"
+ "SUM_CREATED_TMP_TABLES BIGINT unsigned not null,"
+ "SUM_SELECT_FULL_JOIN BIGINT unsigned not null,"
+ "SUM_SELECT_FULL_RANGE_JOIN BIGINT unsigned not null,"
+ "SUM_SELECT_RANGE BIGINT unsigned not null,"
+ "SUM_SELECT_RANGE_CHECK BIGINT unsigned not null,"
+ "SUM_SELECT_SCAN BIGINT unsigned not null,"
+ "SUM_SORT_MERGE_PASSES BIGINT unsigned not null,"
+ "SUM_SORT_RANGE BIGINT unsigned not null,"
+ "SUM_SORT_ROWS BIGINT unsigned not null,"
+ "SUM_SORT_SCAN BIGINT unsigned not null,"
+ "SUM_NO_INDEX_USED BIGINT unsigned not null,"
+ "SUM_NO_GOOD_INDEX_USED BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_statements_summary_by_user_by_event_name("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null,"
+ "SUM_LOCK_TIME BIGINT unsigned not null,"
+ "SUM_ERRORS BIGINT unsigned not null,"
+ "SUM_WARNINGS BIGINT unsigned not null,"
+ "SUM_ROWS_AFFECTED BIGINT unsigned not null,"
+ "SUM_ROWS_SENT BIGINT unsigned not null,"
+ "SUM_ROWS_EXAMINED BIGINT unsigned not null,"
+ "SUM_CREATED_TMP_DISK_TABLES BIGINT unsigned not null,"
+ "SUM_CREATED_TMP_TABLES BIGINT unsigned not null,"
+ "SUM_SELECT_FULL_JOIN BIGINT unsigned not null,"
+ "SUM_SELECT_FULL_RANGE_JOIN BIGINT unsigned not null,"
+ "SUM_SELECT_RANGE BIGINT unsigned not null,"
+ "SUM_SELECT_RANGE_CHECK BIGINT unsigned not null,"
+ "SUM_SELECT_SCAN BIGINT unsigned not null,"
+ "SUM_SORT_MERGE_PASSES BIGINT unsigned not null,"
+ "SUM_SORT_RANGE BIGINT unsigned not null,"
+ "SUM_SORT_ROWS BIGINT unsigned not null,"
+ "SUM_SORT_SCAN BIGINT unsigned not null,"
+ "SUM_NO_INDEX_USED BIGINT unsigned not null,"
+ "SUM_NO_GOOD_INDEX_USED BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME
+--
+
+SET @cmd="CREATE TABLE performance_schema.events_statements_summary_by_account_by_event_name("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "EVENT_NAME VARCHAR(128) not null,"
+ "COUNT_STAR BIGINT unsigned not null,"
+ "SUM_TIMER_WAIT BIGINT unsigned not null,"
+ "MIN_TIMER_WAIT BIGINT unsigned not null,"
+ "AVG_TIMER_WAIT BIGINT unsigned not null,"
+ "MAX_TIMER_WAIT BIGINT unsigned not null,"
+ "SUM_LOCK_TIME BIGINT unsigned not null,"
+ "SUM_ERRORS BIGINT unsigned not null,"
+ "SUM_WARNINGS BIGINT unsigned not null,"
+ "SUM_ROWS_AFFECTED BIGINT unsigned not null,"
+ "SUM_ROWS_SENT BIGINT unsigned not null,"
+ "SUM_ROWS_EXAMINED BIGINT unsigned not null,"
+ "SUM_CREATED_TMP_DISK_TABLES BIGINT unsigned not null,"
+ "SUM_CREATED_TMP_TABLES BIGINT unsigned not null,"
+ "SUM_SELECT_FULL_JOIN BIGINT unsigned not null,"
+ "SUM_SELECT_FULL_RANGE_JOIN BIGINT unsigned not null,"
+ "SUM_SELECT_RANGE BIGINT unsigned not null,"
+ "SUM_SELECT_RANGE_CHECK BIGINT unsigned not null,"
+ "SUM_SELECT_SCAN BIGINT unsigned not null,"
+ "SUM_SORT_MERGE_PASSES BIGINT unsigned not null,"
+ "SUM_SORT_RANGE BIGINT unsigned not null,"
+ "SUM_SORT_ROWS BIGINT unsigned not null,"
+ "SUM_SORT_SCAN BIGINT unsigned not null,"
+ "SUM_NO_INDEX_USED BIGINT unsigned not null,"
+ "SUM_NO_GOOD_INDEX_USED BIGINT unsigned not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
-- TABLE EVENTS_STATEMENTS_SUMMARY_GLOBAL_BY_EVENT_NAME
--
@@ -1054,6 +1285,52 @@ PREPARE stmt FROM @str;
EXECUTE stmt;
DROP PREPARE stmt;
+--
+-- TABLE HOSTS
+--
+
+SET @cmd="CREATE TABLE performance_schema.hosts("
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "CURRENT_CONNECTIONS bigint not null,"
+ "TOTAL_CONNECTIONS bigint not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE USERS
+--
+
+SET @cmd="CREATE TABLE performance_schema.users("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "CURRENT_CONNECTIONS bigint not null,"
+ "TOTAL_CONNECTIONS bigint not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
+-- TABLE ACCOUNTS
+--
+
+SET @cmd="CREATE TABLE performance_schema.accounts("
+ "USER CHAR(16) collate utf8_bin default null,"
+ "HOST CHAR(60) collate utf8_bin default null,"
+ "CURRENT_CONNECTIONS bigint not null,"
+ "TOTAL_CONNECTIONS bigint not null"
+ ")ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
CREATE TABLE IF NOT EXISTS proxies_priv (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Proxied_host char(60) binary DEFAULT '' NOT NULL, Proxied_user char(16) binary DEFAULT '' NOT NULL, With_grant BOOL DEFAULT 0 NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY Host (Host,User,Proxied_host,Proxied_user), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='User proxy privileges';
=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc 2011-04-11 10:28:36 +0000
+++ b/sql/sys_vars.cc 2011-05-07 00:40:25 +0000
@@ -216,6 +216,30 @@ static Sys_var_ulong Sys_pfs_setup_objec
DEFAULT(PFS_MAX_SETUP_OBJECT),
BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
+static Sys_var_ulong Sys_pfs_accounts_size(
+ "performance_schema_accounts_size",
+ "Maximum number of instrumented user@host accounts.",
+ READ_ONLY GLOBAL_VAR(pfs_param.m_account_sizing),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024),
+ DEFAULT(PFS_MAX_ACCOUNT),
+ BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
+
+static Sys_var_ulong Sys_pfs_hosts_size(
+ "performance_schema_hosts_size",
+ "Maximum number of instrumented hosts.",
+ READ_ONLY GLOBAL_VAR(pfs_param.m_host_sizing),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024),
+ DEFAULT(PFS_MAX_HOST),
+ BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
+
+static Sys_var_ulong Sys_pfs_users_size(
+ "performance_schema_users_size",
+ "Maximum number of instrumented users.",
+ READ_ONLY GLOBAL_VAR(pfs_param.m_user_sizing),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024),
+ DEFAULT(PFS_MAX_USER),
+ BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES);
+
static Sys_var_ulong Sys_pfs_max_stage_classes(
"performance_schema_max_stage_classes",
"Maximum number of stage instruments.",
=== modified file 'storage/perfschema/CMakeLists.txt'
--- a/storage/perfschema/CMakeLists.txt 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/CMakeLists.txt 2011-05-07 00:40:25 +0000
@@ -26,7 +26,12 @@ ADD_DEFINITIONS(-DMYSQL_SERVER)
# Tip: ls -1 *.h, ls -1 *.cc
#
SET(PERFSCHEMA_SOURCES ha_perfschema.h
+cursor_by_account.h
+cursor_by_host.h
+cursor_by_thread.h
+cursor_by_user.h
pfs.h
+pfs_account.h
pfs_atomic.h
pfs_column_types.h
pfs_column_values.h
@@ -38,6 +43,7 @@ pfs_events_stages.h
pfs_events_statements.h
pfs_events_waits.h
pfs_global.h
+pfs_host.h
pfs_instr.h
pfs_instr_class.h
pfs_lock.h
@@ -46,21 +52,33 @@ pfs_setup_actor.h
pfs_setup_object.h
pfs_stat.h
pfs_timer.h
+pfs_user.h
pfs_visitor.h
+table_accounts.h
table_all_instr.h
+table_esgs_by_account_by_event_name.h
+table_esgs_by_host_by_event_name.h
table_esgs_by_thread_by_event_name.h
+table_esgs_by_user_by_event_name.h
table_esgs_global_by_event_name.h
+table_esms_by_account_by_event_name.h
+table_esms_by_host_by_event_name.h
table_esms_by_thread_by_event_name.h
+table_esms_by_user_by_event_name.h
table_esms_global_by_event_name.h
table_events_stages.h
table_events_statements.h
table_events_waits.h
table_events_waits_summary.h
+table_ews_by_account_by_event_name.h
+table_ews_by_host_by_event_name.h
table_ews_by_thread_by_event_name.h
+table_ews_by_user_by_event_name.h
table_ews_global_by_event_name.h
table_file_instances.h
table_file_summary.h
table_helper.h
+table_hosts.h
table_os_global_by_type.h
table_performance_timers.h
table_setup_actors.h
@@ -73,8 +91,14 @@ table_threads.h
table_tiws_by_index_usage.h
table_tiws_by_table.h
table_tlws_by_table.h
+table_users.h
+cursor_by_account.cc
+cursor_by_host.cc
+cursor_by_thread.cc
+cursor_by_user.cc
ha_perfschema.cc
pfs.cc
+pfs_account.cc
pfs_atomic.cc
pfs_check.cc
pfs_column_values.cc
@@ -85,27 +109,40 @@ pfs_events_stages.cc
pfs_events_statements.cc
pfs_events_waits.cc
pfs_global.cc
+pfs_host.cc
pfs_instr.cc
pfs_instr_class.cc
pfs_server.cc
pfs_setup_actor.cc
pfs_setup_object.cc
pfs_timer.cc
+pfs_user.cc
pfs_visitor.cc
+table_accounts.cc
table_all_instr.cc
+table_esgs_by_account_by_event_name.cc
+table_esgs_by_host_by_event_name.cc
table_esgs_by_thread_by_event_name.cc
+table_esgs_by_user_by_event_name.cc
table_esgs_global_by_event_name.cc
+table_esms_by_account_by_event_name.cc
+table_esms_by_host_by_event_name.cc
table_esms_by_thread_by_event_name.cc
+table_esms_by_user_by_event_name.cc
table_esms_global_by_event_name.cc
table_events_stages.cc
table_events_statements.cc
table_events_waits.cc
table_events_waits_summary.cc
+table_ews_by_account_by_event_name.cc
+table_ews_by_host_by_event_name.cc
table_ews_by_thread_by_event_name.cc
+table_ews_by_user_by_event_name.cc
table_ews_global_by_event_name.cc
table_file_instances.cc
table_file_summary.cc
table_helper.cc
+table_hosts.cc
table_os_global_by_type.cc
table_performance_timers.cc
table_setup_actors.cc
@@ -118,6 +155,7 @@ table_threads.cc
table_tiws_by_index_usage.cc
table_tiws_by_table.cc
table_tlws_by_table.cc
+table_users.cc
)
MYSQL_ADD_PLUGIN(perfschema ${PERFSCHEMA_SOURCES} STORAGE_ENGINE DEFAULT STATIC_ONLY)
=== added file 'storage/perfschema/cursor_by_account.cc'
--- a/storage/perfschema/cursor_by_account.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_account.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,72 @@
+/* Copyright (c) 2011, 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 */
+
+/**
+ @file storage/perfschema/cursor_by_account.cc
+ Cursor CURSOR_BY_ACCOUNT (implementation).
+*/
+
+#include "my_global.h"
+#include "cursor_by_account.h"
+#include "pfs_user.h"
+
+cursor_by_account::cursor_by_account(const PFS_engine_table_share *share)
+ : PFS_engine_table(share, &m_pos),
+ m_pos(0), m_next_pos(0)
+{}
+
+void cursor_by_account::reset_position(void)
+{
+ m_pos.m_index= 0;
+ m_next_pos.m_index= 0;
+}
+
+int cursor_by_account::rnd_next(void)
+{
+ PFS_account *pfs;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.m_index < account_max;
+ m_pos.next())
+ {
+ pfs= &account_array[m_pos.m_index];
+ if (pfs->m_lock.is_populated())
+ {
+ make_row(pfs);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+cursor_by_account::rnd_pos(const void *pos)
+{
+ PFS_account *pfs;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index < account_max);
+ pfs= &account_array[m_pos.m_index];
+ if (pfs->m_lock.is_populated())
+ {
+ make_row(pfs);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
=== added file 'storage/perfschema/cursor_by_account.h'
--- a/storage/perfschema/cursor_by_account.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_account.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,59 @@
+/* Copyright (c) 2011, 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 */
+
+#ifndef CURSOR_BY_ACCOUNT_H
+#define CURSOR_BY_ACCOUNT_H
+
+/**
+ @file storage/perfschema/cursor_by_account.h
+ Cursor CURSOR_BY_ACCOUNT (declarations).
+*/
+
+#include "pfs_engine_table.h"
+#include "pfs_account.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/** Cursor CURSOR_BY_ACCOUNT. */
+class cursor_by_account : public PFS_engine_table
+{
+public:
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ cursor_by_account(const PFS_engine_table_share *share);
+
+public:
+ ~cursor_by_account()
+ {}
+
+protected:
+ virtual void make_row(PFS_account *account)= 0;
+
+private:
+ /** Current position. */
+ PFS_simple_index m_pos;
+ /** Next position. */
+ PFS_simple_index m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/cursor_by_host.cc'
--- a/storage/perfschema/cursor_by_host.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_host.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,72 @@
+/* Copyright (c) 2011, 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 */
+
+/**
+ @file storage/perfschema/cursor_by_host.cc
+ Cursor CURSOR_BY_HOST (implementation).
+*/
+
+#include "my_global.h"
+#include "cursor_by_host.h"
+#include "pfs_host.h"
+
+cursor_by_host::cursor_by_host(const PFS_engine_table_share *share)
+ : PFS_engine_table(share, &m_pos),
+ m_pos(0), m_next_pos(0)
+{}
+
+void cursor_by_host::reset_position(void)
+{
+ m_pos.m_index= 0;
+ m_next_pos.m_index= 0;
+}
+
+int cursor_by_host::rnd_next(void)
+{
+ PFS_host *host;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.m_index < host_max;
+ m_pos.next())
+ {
+ host= & host_array[m_pos.m_index];
+ if (host->m_lock.is_populated())
+ {
+ make_row(host);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+cursor_by_host::rnd_pos(const void *pos)
+{
+ PFS_host *pfs;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index < host_max);
+ pfs= &host_array[m_pos.m_index];
+ if (pfs->m_lock.is_populated())
+ {
+ make_row(pfs);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
=== added file 'storage/perfschema/cursor_by_host.h'
--- a/storage/perfschema/cursor_by_host.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_host.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,59 @@
+/* Copyright (c) 2011, 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 */
+
+#ifndef CURSOR_BY_HOST_H
+#define CURSOR_BY_HOST_H
+
+/**
+ @file storage/perfschema/cursor_by_host.h
+ Cursor CURSOR_BY_HOST (declarations).
+*/
+
+#include "pfs_engine_table.h"
+#include "pfs_host.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/** Cursor CURSOR_BY_HOST. */
+class cursor_by_host : public PFS_engine_table
+{
+public:
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ cursor_by_host(const PFS_engine_table_share *share);
+
+public:
+ ~cursor_by_host()
+ {}
+
+protected:
+ virtual void make_row(PFS_host *host)= 0;
+
+private:
+ /** Current position. */
+ PFS_simple_index m_pos;
+ /** Next position. */
+ PFS_simple_index m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/cursor_by_thread.cc'
--- a/storage/perfschema/cursor_by_thread.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_thread.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,72 @@
+/* Copyright (c) 2011, 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 */
+
+/**
+ @file storage/perfschema/cursor_by_thread.cc
+ Cursor CURSOR_BY_THREAD (implementation).
+*/
+
+#include "my_global.h"
+#include "cursor_by_thread.h"
+#include "pfs_instr.h"
+
+cursor_by_thread::cursor_by_thread(const PFS_engine_table_share *share)
+ : PFS_engine_table(share, &m_pos),
+ m_pos(0), m_next_pos(0)
+{}
+
+void cursor_by_thread::reset_position(void)
+{
+ m_pos.m_index= 0;
+ m_next_pos.m_index= 0;
+}
+
+int cursor_by_thread::rnd_next(void)
+{
+ PFS_thread *pfs;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.m_index < thread_max;
+ m_pos.next())
+ {
+ pfs= &thread_array[m_pos.m_index];
+ if (pfs->m_lock.is_populated())
+ {
+ make_row(pfs);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+cursor_by_thread::rnd_pos(const void *pos)
+{
+ PFS_thread *pfs;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index < thread_max);
+ pfs= &thread_array[m_pos.m_index];
+ if (pfs->m_lock.is_populated())
+ {
+ make_row(pfs);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
=== added file 'storage/perfschema/cursor_by_thread.h'
--- a/storage/perfschema/cursor_by_thread.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_thread.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,59 @@
+/* Copyright (c) 2011, 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 */
+
+#ifndef CURSOR_BY_THREAD_H
+#define CURSOR_BY_THREAD_H
+
+/**
+ @file storage/perfschema/cursor_by_thread.h
+ Cursor CURSOR_BY_THREAD (declarations).
+*/
+
+#include "pfs_engine_table.h"
+#include "pfs_instr.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/** Cursor CURSOR_BY_THREAD. */
+class cursor_by_thread : public PFS_engine_table
+{
+public:
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ cursor_by_thread(const PFS_engine_table_share *share);
+
+public:
+ ~cursor_by_thread()
+ {}
+
+protected:
+ virtual void make_row(PFS_thread *thread)= 0;
+
+private:
+ /** Current position. */
+ PFS_simple_index m_pos;
+ /** Next position. */
+ PFS_simple_index m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/cursor_by_user.cc'
--- a/storage/perfschema/cursor_by_user.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_user.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,72 @@
+/* Copyright (c) 2011, 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 */
+
+/**
+ @file storage/perfschema/cursor_by_user.cc
+ Cursor CURSOR_BY_USER (implementation).
+*/
+
+#include "my_global.h"
+#include "cursor_by_user.h"
+#include "pfs_user.h"
+
+cursor_by_user::cursor_by_user(const PFS_engine_table_share *share)
+ : PFS_engine_table(share, &m_pos),
+ m_pos(0), m_next_pos(0)
+{}
+
+void cursor_by_user::reset_position(void)
+{
+ m_pos.m_index= 0;
+ m_next_pos.m_index= 0;
+}
+
+int cursor_by_user::rnd_next(void)
+{
+ PFS_user *pfs;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.m_index < user_max;
+ m_pos.next())
+ {
+ pfs= &user_array[m_pos.m_index];
+ if (pfs->m_lock.is_populated())
+ {
+ make_row(pfs);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+cursor_by_user::rnd_pos(const void *pos)
+{
+ PFS_user *pfs;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index < user_max);
+ pfs= &user_array[m_pos.m_index];
+ if (pfs->m_lock.is_populated())
+ {
+ make_row(pfs);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
=== added file 'storage/perfschema/cursor_by_user.h'
--- a/storage/perfschema/cursor_by_user.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/cursor_by_user.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,59 @@
+/* Copyright (c) 2011, 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 */
+
+#ifndef CURSOR_BY_USER_H
+#define CURSOR_BY_USER_H
+
+/**
+ @file storage/perfschema/cursor_by_user.h
+ Cursor CURSOR_BY_USER (declarations).
+*/
+
+#include "pfs_engine_table.h"
+#include "pfs_user.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/** Cursor CURSOR_BY_USER. */
+class cursor_by_user : public PFS_engine_table
+{
+public:
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ cursor_by_user(const PFS_engine_table_share *share);
+
+public:
+ ~cursor_by_user()
+ {}
+
+protected:
+ virtual void make_row(PFS_user *user)= 0;
+
+private:
+ /** Current position. */
+ PFS_simple_index m_pos;
+ /** Next position. */
+ PFS_simple_index m_next_pos;
+};
+
+/** @} */
+#endif
=== modified file 'storage/perfschema/ha_perfschema.cc'
--- a/storage/perfschema/ha_perfschema.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/ha_perfschema.cc 2011-05-07 00:40:25 +0000
@@ -28,6 +28,9 @@
#include "pfs_column_values.h"
#include "pfs_instr_class.h"
#include "pfs_instr.h"
+#include "pfs_host.h"
+#include "pfs_user.h"
+#include "pfs_account.h"
#ifdef MY_ATOMIC_MODE_DUMMY
/*
@@ -146,6 +149,12 @@ static struct st_mysql_show_var pfs_stat
/* table handles, can be flushed */
{"Performance_schema_table_handles_lost",
(char*) &table_lost, SHOW_LONG},
+ {"Performance_schema_hosts_lost",
+ (char*) &host_lost, SHOW_LONG},
+ {"Performance_schema_users_lost",
+ (char*) &user_lost, SHOW_LONG},
+ {"Performance_schema_accounts_lost",
+ (char*) &user_lost, SHOW_LONG},
{"Performance_schema_stage_classes_lost",
(char*) &stage_class_lost, SHOW_LONG},
{"Performance_schema_statement_classes_lost",
=== modified file 'storage/perfschema/pfs.cc'
--- a/storage/perfschema/pfs.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs.cc 2011-05-07 00:40:25 +0000
@@ -21,11 +21,15 @@
#include "my_global.h"
#include "thr_lock.h"
#include "mysql/psi/psi.h"
+#include "mysql/psi/mysql_thread.h"
#include "my_pthread.h"
#include "sql_const.h"
#include "pfs.h"
#include "pfs_instr_class.h"
#include "pfs_instr.h"
+#include "pfs_host.h"
+#include "pfs_user.h"
+#include "pfs_account.h"
#include "pfs_global.h"
#include "pfs_column_values.h"
#include "pfs_timer.h"
@@ -35,6 +39,7 @@
#include "pfs_setup_actor.h"
#include "pfs_setup_object.h"
#include "sql_error.h"
+#include "sp_head.h"
/**
@page PAGE_PERFORMANCE_SCHEMA The Performance Schema main page
@@ -715,7 +720,7 @@ static inline int mysql_mutex_lock(...)
|
| [3]
|
- 3a |-> pfs_user_host(U, H).event_name(M) =====>> [D], [E], [F]
+ 3a |-> pfs_account(U, H).event_name(M) =====>> [D], [E], [F]
| |
| | [4]
| |
@@ -748,8 +753,8 @@ static inline int mysql_mutex_lock(...)
Not implemented:
- [3] thread disconnect
- [4] user host disconnect
- - [D] EVENTS_WAITS_SUMMARY_BY_USER_HOST_BY_EVENT_NAME,
- table_ews_by_user_host_by_event_name::make_row()
+ - [D] EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME,
+ table_ews_by_account_by_event_name::make_row()
- [E] EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME,
table_ews_by_user_by_event_name::make_row()
- [F] EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME,
@@ -898,7 +903,7 @@ static inline int mysql_mutex_lock(...)
| |
| | [2]
| |
- | a |-> pfs_user_host(U, H).event_name(S) =====>> [B], [C], [D], [E]
+ | a |-> pfs_account(U, H).event_name(S) =====>> [B], [C], [D], [E]
| | |
| | | [3]
| | |
@@ -924,8 +929,8 @@ static inline int mysql_mutex_lock(...)
- [2a, 2b, 2c] @c delete_thread_v1() to aggregate to user/host buffers
- [3] user disconnect
- [4] host disconnect
- - [B] EVENTS_STAGES_SUMMARY_BY_USER_HOST_BY_EVENT_NAME,
- @c table_esgs_by_user_host_by_event_name::make_row()
+ - [B] EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME,
+ @c table_esgs_by_account_by_event_name::make_row()
- [C] EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME,
@c table_esgs_by_user_by_event_name::make_row()
- [D] EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME,
@@ -942,7 +947,7 @@ static inline int mysql_mutex_lock(...)
| |
| | [2]
| |
- | a |-> pfs_user_host(U, H).event_name(S) =====>> [B], [C], [D], [E]
+ | a |-> pfs_account(U, H).event_name(S) =====>> [B], [C], [D], [E]
| | |
| | | [3]
| | |
@@ -968,8 +973,8 @@ static inline int mysql_mutex_lock(...)
- [2a, 2b, 2c] @c delete_thread_v1() to aggregate to user/host buffers
- [3] user disconnect
- [4] host disconnect
- - [B] EVENTS_STATEMENTS_SUMMARY_BY_USER_HOST_BY_EVENT_NAME,
- @c table_esms_by_user_host_by_event_name::make_row()
+ - [B] EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME,
+ @c table_esms_by_account_by_event_name::make_row()
- [C] EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME,
@c table_esms_by_user_by_event_name::make_row()
- [D] EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME,
@@ -1542,6 +1547,8 @@ void* pfs_spawn_thread(void *arg)
{
PFS_thread *parent= typed_arg->m_parent_thread;
+ clear_thread_account(pfs);
+
pfs->m_parent_thread_internal_id= parent->m_thread_internal_id;
memcpy(pfs->m_username, parent->m_username, sizeof(pfs->m_username));
@@ -1549,6 +1556,8 @@ void* pfs_spawn_thread(void *arg)
memcpy(pfs->m_hostname, parent->m_hostname, sizeof(pfs->m_hostname));
pfs->m_hostname_length= parent->m_hostname_length;
+
+ set_thread_account(pfs);
}
}
else
@@ -1660,10 +1669,14 @@ static void set_thread_user_v1(const cha
pfs->m_lock.allocated_to_dirty();
+ clear_thread_account(pfs);
+
if (user_len > 0)
memcpy(pfs->m_username, user, user_len);
pfs->m_username_length= user_len;
+ set_thread_account(pfs);
+
bool enabled= true;
if (flag_thread_instrumentation)
{
@@ -1689,9 +1702,9 @@ static void set_thread_user_v1(const cha
/**
Implementation of the thread instrumentation interface.
- @sa PSI_v1::set_thread_user_host.
+ @sa PSI_v1::set_thread_account.
*/
-static void set_thread_user_host_v1(const char *user, int user_len,
+static void set_thread_account_v1(const char *user, int user_len,
const char *host, int host_len)
{
PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
@@ -1708,6 +1721,8 @@ static void set_thread_user_host_v1(cons
pfs->m_lock.allocated_to_dirty();
+ clear_thread_account(pfs);
+
if (host_len > 0)
memcpy(pfs->m_hostname, host, host_len);
pfs->m_hostname_length= host_len;
@@ -1716,6 +1731,8 @@ static void set_thread_user_host_v1(cons
memcpy(pfs->m_username, user, user_len);
pfs->m_username_length= user_len;
+ set_thread_account(pfs);
+
bool enabled= true;
if (flag_thread_instrumentation)
{
@@ -3597,7 +3614,6 @@ static void end_file_wait_v1(PSI_file_lo
}
}
-
static void start_stage_v1(PSI_stage_key key, const char *src_file, int src_line)
{
ulonglong timer_value= 0;
@@ -4220,6 +4236,7 @@ static void end_statement_v1(PSI_stateme
break;
}
}
+
/**
Implementation of the instrumentation interface.
@sa PSI_v1.
@@ -4250,7 +4267,7 @@ PSI_v1 PFS_v1=
set_thread_id_v1,
get_thread_v1,
set_thread_user_v1,
- set_thread_user_host_v1,
+ set_thread_account_v1,
set_thread_db_v1,
set_thread_command_v1,
set_thread_start_time_v1,
=== added file 'storage/perfschema/pfs_account.cc'
--- a/storage/perfschema/pfs_account.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_account.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,452 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/pfs_account.cc
+ Performance schema user@host (implementation).
+*/
+
+#include "my_global.h"
+#include "my_sys.h"
+#include "pfs.h"
+#include "pfs_stat.h"
+#include "pfs_instr.h"
+#include "pfs_setup_actor.h"
+#include "pfs_host.h"
+#include "pfs_host.h"
+#include "pfs_user.h"
+#include "pfs_account.h"
+#include "pfs_global.h"
+#include "pfs_instr_class.h"
+
+/**
+ @addtogroup Performance_schema_buffers
+ @{
+*/
+
+ulong account_max;
+ulong account_lost;
+
+PFS_account *account_array= NULL;
+
+static PFS_single_stat *account_instr_class_waits_array= NULL;
+static PFS_stage_stat *account_instr_class_stages_array= NULL;
+static PFS_statement_stat *account_instr_class_statements_array= NULL;
+
+static LF_HASH account_hash;
+static bool account_hash_inited= false;
+
+/**
+ Initialize the user buffers.
+ @param param sizing parameters
+ @return 0 on success
+*/
+int init_account(const PFS_global_param *param)
+{
+ uint index;
+
+ account_max= param->m_account_sizing;
+
+ account_array= NULL;
+ account_instr_class_waits_array= NULL;
+ account_instr_class_stages_array= NULL;
+ account_instr_class_statements_array= NULL;
+ uint waits_sizing= account_max * wait_class_max;
+ uint stages_sizing= account_max * stage_class_max;
+ uint statements_sizing= account_max * statement_class_max;
+
+ if (account_max > 0)
+ {
+ account_array= PFS_MALLOC_ARRAY(account_max, PFS_account,
+ MYF(MY_ZEROFILL));
+ if (unlikely(account_array == NULL))
+ return 1;
+ }
+
+ if (waits_sizing > 0)
+ {
+ account_instr_class_waits_array=
+ PFS_connection_slice::alloc_waits_slice(waits_sizing);
+ if (unlikely(account_instr_class_waits_array == NULL))
+ return 1;
+ }
+
+ if (stages_sizing > 0)
+ {
+ account_instr_class_stages_array=
+ PFS_connection_slice::alloc_stages_slice(stages_sizing);
+ if (unlikely(account_instr_class_stages_array == NULL))
+ return 1;
+ }
+
+ if (statements_sizing > 0)
+ {
+ account_instr_class_statements_array=
+ PFS_connection_slice::alloc_statements_slice(statements_sizing);
+ if (unlikely(account_instr_class_statements_array == NULL))
+ return 1;
+ }
+
+ for (index= 0; index < account_max; index++)
+ {
+ account_array[index].m_instr_class_waits_stats=
+ &account_instr_class_waits_array[index * wait_class_max];
+ account_array[index].m_instr_class_stages_stats=
+ &account_instr_class_stages_array[index * stage_class_max];
+ account_array[index].m_instr_class_statements_stats=
+ &account_instr_class_statements_array[index * statement_class_max];
+ }
+
+ return 0;
+}
+
+/** Cleanup all the user buffers. */
+void cleanup_account(void)
+{
+ pfs_free(account_array);
+ account_array= NULL;
+ pfs_free(account_instr_class_waits_array);
+ account_instr_class_waits_array= NULL;
+ account_max= 0;
+}
+
+static uchar *account_hash_get_key(const uchar *entry, size_t *length,
+ my_bool)
+{
+ const PFS_account * const *typed_entry;
+ const PFS_account *account;
+ const void *result;
+ typed_entry= reinterpret_cast<const PFS_account* const *> (entry);
+ DBUG_ASSERT(typed_entry != NULL);
+ account= *typed_entry;
+ DBUG_ASSERT(account != NULL);
+ *length= account->m_key.m_key_length;
+ result= account->m_key.m_hash_key;
+ return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
+}
+
+/**
+ Initialize the user hash.
+ @return 0 on success
+*/
+int init_account_hash(void)
+{
+ if (! account_hash_inited)
+ {
+ lf_hash_init(&account_hash, sizeof(PFS_account*), LF_HASH_UNIQUE,
+ 0, 0, account_hash_get_key, &my_charset_bin);
+ account_hash_inited= true;
+ }
+ return 0;
+}
+
+/** Cleanup the user hash. */
+void cleanup_account_hash(void)
+{
+ if (account_hash_inited)
+ {
+ lf_hash_destroy(&account_hash);
+ account_hash_inited= false;
+ }
+}
+
+static LF_PINS* get_account_hash_pins(PFS_thread *thread)
+{
+ if (unlikely(thread->m_account_hash_pins == NULL))
+ {
+ if (! account_hash_inited)
+ return NULL;
+ thread->m_account_hash_pins= lf_hash_get_pins(&account_hash);
+ }
+ return thread->m_account_hash_pins;
+}
+
+static void set_account_key(PFS_account_key *key,
+ const char *user, uint user_length,
+ const char *host, uint host_length)
+{
+ DBUG_ASSERT(user_length <= USERNAME_LENGTH);
+ DBUG_ASSERT(host_length <= HOSTNAME_LENGTH);
+
+ char *ptr= &key->m_hash_key[0];
+ if (user_length > 0)
+ {
+ memcpy(ptr, user, user_length);
+ ptr+= user_length;
+ }
+ ptr[0]= 0;
+ ptr++;
+ if (host_length > 0)
+ {
+ memcpy(ptr, host, host_length);
+ ptr+= host_length;
+ }
+ ptr[0]= 0;
+ ptr++;
+ key->m_key_length= ptr - &key->m_hash_key[0];
+}
+
+PFS_account *
+find_or_create_account(PFS_thread *thread,
+ const char *username, uint username_length,
+ const char *hostname, uint hostname_length)
+{
+ if (account_max == 0)
+ {
+ account_lost++;
+ return NULL;
+ }
+
+ LF_PINS *pins= get_account_hash_pins(thread);
+ if (unlikely(pins == NULL))
+ {
+ account_lost++;
+ return NULL;
+ }
+
+ PFS_account_key key;
+ set_account_key(&key, username, username_length,
+ hostname, hostname_length);
+
+ PFS_account **entry;
+ uint retry_count= 0;
+ const uint retry_max= 3;
+
+search:
+ entry= reinterpret_cast<PFS_account**>
+ (lf_hash_search(&account_hash, pins,
+ key.m_hash_key, key.m_key_length));
+ if (entry && (entry != MY_ERRPTR))
+ {
+ PFS_account *pfs;
+ pfs= *entry;
+ pfs->inc_refcount();
+ lf_hash_search_unpin(pins);
+ return pfs;
+ }
+
+ PFS_scan scan;
+ uint random= randomized_index(username, account_max);
+
+ for (scan.init(random, account_max);
+ scan.has_pass();
+ scan.next_pass())
+ {
+ PFS_account *pfs= account_array + scan.first();
+ PFS_account *pfs_last= account_array + scan.last();
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_free())
+ {
+ if (pfs->m_lock.free_to_dirty())
+ {
+ pfs->m_key= key;
+ if (username_length > 0)
+ pfs->m_username= &pfs->m_key.m_hash_key[0];
+ else
+ pfs->m_username= NULL;
+ pfs->m_username_length= username_length;
+
+ if (hostname_length > 0)
+ pfs->m_hostname= &pfs->m_key.m_hash_key[username_length + 1];
+ else
+ pfs->m_hostname= NULL;
+ pfs->m_hostname_length= hostname_length;
+
+ pfs->m_user= find_or_create_user(thread, username, username_length);
+ pfs->m_host= find_or_create_host(thread, hostname, hostname_length);
+
+ pfs->init_refcount();
+ pfs->reset_stats();
+ pfs->m_disconnected_count= 0;
+
+ int res;
+ res= lf_hash_insert(&account_hash, pins, &pfs);
+ if (likely(res == 0))
+ {
+ pfs->m_lock.dirty_to_allocated();
+ return pfs;
+ }
+
+ if (pfs->m_user)
+ {
+ pfs->m_user->release();
+ pfs->m_user= NULL;
+ }
+ if (pfs->m_host)
+ {
+ pfs->m_host->release();
+ pfs->m_host= NULL;
+ }
+
+ pfs->m_lock.dirty_to_free();
+
+ if (res > 0)
+ {
+ if (++retry_count > retry_max)
+ {
+ account_lost++;
+ return NULL;
+ }
+ goto search;
+ }
+
+ account_lost++;
+ return NULL;
+ }
+ }
+ }
+ }
+
+ account_lost++;
+ return NULL;
+}
+
+void PFS_account::aggregate()
+{
+ aggregate_waits();
+
+ if (likely(m_user != NULL && m_host != NULL))
+ {
+ m_user->m_disconnected_count+= m_disconnected_count;
+ m_host->m_disconnected_count+= m_disconnected_count;
+ m_disconnected_count= 0;
+ }
+ else
+ {
+ if (m_user != NULL)
+ {
+ m_user->m_disconnected_count+= m_disconnected_count;
+ m_disconnected_count= 0;
+ }
+ else if (m_host != NULL)
+ {
+ m_host->m_disconnected_count+= m_disconnected_count;
+ m_disconnected_count= 0;
+ }
+ }
+}
+
+void PFS_account::aggregate_waits()
+{
+ if (likely(m_user != NULL && m_host != NULL))
+ {
+ /*
+ Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
+ - EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME
+ - EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME
+ in parallel.
+ */
+ aggregate_all_event_names(m_instr_class_waits_stats,
+ m_user->m_instr_class_waits_stats,
+ m_host->m_instr_class_waits_stats);
+ }
+ else
+ {
+ if (m_user != NULL)
+ {
+ /*
+ Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
+ - EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME
+ */
+ aggregate_all_event_names(m_instr_class_waits_stats,
+ m_user->m_instr_class_waits_stats);
+ }
+ else if (m_host != NULL)
+ {
+ /*
+ Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
+ - EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME
+ */
+ aggregate_all_event_names(m_instr_class_waits_stats,
+ m_host->m_instr_class_waits_stats);
+ }
+ }
+}
+
+void PFS_account::release()
+{
+ dec_refcount();
+}
+
+PFS_account *sanitize_account(PFS_account *unsafe)
+{
+ if ((&account_array[0] <= unsafe) &&
+ (unsafe < &account_array[account_max]))
+ return unsafe;
+ return NULL;
+}
+
+void purge_account(PFS_thread *thread, PFS_account *account)
+{
+ account->aggregate();
+
+ LF_PINS *pins= get_account_hash_pins(thread);
+ if (unlikely(pins == NULL))
+ return;
+
+ PFS_account **entry;
+ entry= reinterpret_cast<PFS_account**>
+ (lf_hash_search(&account_hash, pins,
+ account->m_key.m_hash_key,
+ account->m_key.m_key_length));
+ if (entry && (entry != MY_ERRPTR))
+ {
+ PFS_account *pfs;
+ pfs= *entry;
+ DBUG_ASSERT(pfs == account);
+ if (account->get_refcount() == 0)
+ {
+ lf_hash_delete(&account_hash, pins,
+ account->m_key.m_hash_key,
+ account->m_key.m_key_length);
+ if (account->m_user != NULL)
+ {
+ account->m_user->release();
+ account->m_user= NULL;
+ }
+ if (account->m_host != NULL)
+ {
+ account->m_host->release();
+ account->m_host= NULL;
+ }
+ account->m_lock.allocated_to_free();
+ }
+ lf_hash_search_unpin(pins);
+ }
+}
+
+/** Purge non connected user@host, reset stats of connected user@host. */
+void purge_all_account(void)
+{
+ PFS_thread *thread= PFS_thread::get_current_thread();
+ if (unlikely(thread == NULL))
+ return;
+
+ PFS_account *pfs= account_array;
+ PFS_account *pfs_last= account_array + account_max;
+
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ pfs->m_disconnected_count= 0;
+ if (pfs->get_refcount() == 0)
+ purge_account(thread, pfs);
+ }
+ }
+}
+
+/** @} */
=== added file 'storage/perfschema/pfs_account.h'
--- a/storage/perfschema/pfs_account.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_account.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,117 @@
+/* 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 */
+
+#ifndef PFS_ACCOUNT_H
+#define PFS_ACCOUNT_H
+
+/**
+ @file storage/perfschema/pfs_account.h
+ Performance schema user@host (declarations).
+*/
+
+#include "pfs_lock.h"
+#include "lf.h"
+#include "pfs_con_slice.h"
+
+struct PFS_global_param;
+struct PFS_user;
+struct PFS_host;
+struct PFS_thread;
+
+/**
+ @addtogroup Performance_schema_buffers
+ @{
+*/
+
+struct PFS_account_key
+{
+ /**
+ Hash search key.
+ This has to be a string for LF_HASH,
+ the format is "<username><0x00><hostname><0x00>"
+ */
+ char m_hash_key[USERNAME_LENGTH + 1 + HOSTNAME_LENGTH + 1];
+ uint m_key_length;
+};
+
+struct PFS_account : PFS_connection_slice
+{
+public:
+ inline void init_refcount(void)
+ {
+ PFS_atomic::store_32(& m_refcount, 1);
+ }
+
+ inline int get_refcount(void)
+ {
+ return PFS_atomic::load_32(& m_refcount);
+ }
+
+ inline void inc_refcount(void)
+ {
+ PFS_atomic::add_32(& m_refcount, 1);
+ }
+
+ inline void dec_refcount(void)
+ {
+ PFS_atomic::add_32(& m_refcount, -1);
+ }
+
+ void aggregate(void);
+ void aggregate_waits(void);
+ void release(void);
+
+ /** Internal lock. */
+ pfs_lock m_lock;
+ PFS_account_key m_key;
+ const char *m_username;
+ uint m_username_length;
+ const char *m_hostname;
+ uint m_hostname_length;
+ PFS_user *m_user;
+ PFS_host *m_host;
+
+ ulonglong m_disconnected_count;
+
+private:
+ int m_refcount;
+};
+
+int init_account(const PFS_global_param *param);
+void cleanup_account(void);
+int init_account_hash(void);
+void cleanup_account_hash(void);
+
+PFS_account *
+find_or_create_account(PFS_thread *thread,
+ const char *username, uint username_length,
+ const char *hostname, uint hostname_length);
+
+PFS_account *sanitize_account(PFS_account *unsafe);
+void purge_all_account(void);
+
+
+/* For iterators and show status. */
+
+extern ulong account_max;
+extern ulong account_lost;
+
+/* Exposing the data directly, for iterators. */
+
+extern PFS_account *account_array;
+
+/** @} */
+#endif
+
=== modified file 'storage/perfschema/pfs_engine_table.cc'
--- a/storage/perfschema/pfs_engine_table.cc 2011-02-15 14:31:13 +0000
+++ b/storage/perfschema/pfs_engine_table.cc 2011-05-07 00:40:25 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2011, 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
@@ -18,6 +18,8 @@
Performance schema tables (implementation).
*/
+#include "my_global.h"
+#include "my_pthread.h"
#include "pfs_engine_table.h"
#include "table_events_waits.h"
@@ -35,18 +37,32 @@
#include "table_file_instances.h"
#include "table_file_summary.h"
#include "table_threads.h"
+
+#include "table_ews_by_host_by_event_name.h"
+#include "table_ews_by_user_by_event_name.h"
+#include "table_ews_by_account_by_event_name.h"
#include "table_tiws_by_index_usage.h"
#include "table_tiws_by_table.h"
#include "table_tlws_by_table.h"
#include "table_events_stages.h"
#include "table_esgs_by_thread_by_event_name.h"
+#include "table_esgs_by_host_by_event_name.h"
+#include "table_esgs_by_user_by_event_name.h"
+#include "table_esgs_by_account_by_event_name.h"
#include "table_esgs_global_by_event_name.h"
#include "table_events_statements.h"
#include "table_esms_by_thread_by_event_name.h"
+#include "table_esms_by_host_by_event_name.h"
+#include "table_esms_by_user_by_event_name.h"
+#include "table_esms_by_account_by_event_name.h"
#include "table_esms_global_by_event_name.h"
+#include "table_users.h"
+#include "table_accounts.h"
+#include "table_hosts.h"
+
/* For show status */
#include "pfs_column_values.h"
#include "pfs_instr.h"
@@ -66,10 +82,13 @@ static PFS_engine_table_share *all_share
{
&table_cond_instances::m_share,
&table_events_waits_current::m_share,
- &table_events_waits_history_long::m_share,
&table_events_waits_history::m_share,
+ &table_events_waits_history_long::m_share,
+ &table_ews_by_host_by_event_name::m_share,
&table_events_waits_summary_by_instance::m_share,
&table_ews_by_thread_by_event_name::m_share,
+ &table_ews_by_user_by_event_name::m_share,
+ &table_ews_by_account_by_event_name::m_share,
&table_ews_global_by_event_name::m_share,
&table_file_instances::m_share,
&table_file_summary_by_event_name::m_share,
@@ -83,23 +102,32 @@ static PFS_engine_table_share *all_share
&table_setup_instruments::m_share,
&table_setup_objects::m_share,
&table_setup_timers::m_share,
- &table_threads::m_share,
&table_tiws_by_index_usage::m_share,
&table_tiws_by_table::m_share,
&table_tlws_by_table::m_share,
+ &table_threads::m_share,
&table_events_stages_current::m_share,
&table_events_stages_history::m_share,
&table_events_stages_history_long::m_share,
&table_esgs_by_thread_by_event_name::m_share,
+ &table_esgs_by_account_by_event_name::m_share,
+ &table_esgs_by_user_by_event_name::m_share,
+ &table_esgs_by_host_by_event_name::m_share,
&table_esgs_global_by_event_name::m_share,
&table_events_statements_current::m_share,
&table_events_statements_history::m_share,
&table_events_statements_history_long::m_share,
&table_esms_by_thread_by_event_name::m_share,
+ &table_esms_by_account_by_event_name::m_share,
+ &table_esms_by_user_by_event_name::m_share,
+ &table_esms_by_host_by_event_name::m_share,
&table_esms_global_by_event_name::m_share,
+ &table_users::m_share,
+ &table_accounts::m_share,
+ &table_hosts::m_share,
NULL
};
@@ -114,7 +142,7 @@ void PFS_engine_table_share::check_all_t
DBUG_EXECUTE_IF("tampered_perfschema_table1",
{
/* Hack SETUP_INSTRUMENT, incompatible change. */
- all_shares[16]->m_field_def->count++;
+ all_shares[24]->m_field_def->count++;
});
for (current= &all_shares[0]; (*current) != NULL; current++)
@@ -926,146 +954,302 @@ bool pfs_show_status(handlerton *hton, T
total_memory+= size;
break;
case 59:
+ name= "(pfs_account).row_size";
+ size= sizeof(PFS_account);
+ break;
+ case 60:
+ name= "(pfs_account).row_count";
+ size= account_max;
+ break;
+ case 61:
+ name= "(pfs_account).memory";
+ size= account_max * sizeof(PFS_account);
+ total_memory+= size;
+ break;
+ case 62:
+ name= "events_waits_summary_by_account_by_event_name.row_size";
+ size= sizeof(PFS_single_stat);
+ break;
+ case 63:
+ name= "events_waits_summary_by_account_by_event_name.row_count";
+ size= account_max * wait_class_max;
+ break;
+ case 64:
+ name= "events_waits_summary_by_account_by_event_name.memory";
+ size= account_max * wait_class_max * sizeof(PFS_single_stat);
+ total_memory+= size;
+ break;
+ case 65:
+ name= "events_waits_summary_by_user_by_event_name.row_size";
+ size= sizeof(PFS_single_stat);
+ break;
+ case 66:
+ name= "events_waits_summary_by_user_by_event_name.row_count";
+ size= user_max * wait_class_max;
+ break;
+ case 67:
+ name= "events_waits_summary_by_user_by_event_name.memory";
+ size= user_max * wait_class_max * sizeof(PFS_single_stat);
+ total_memory+= size;
+ break;
+ case 68:
+ name= "events_waits_summary_by_host_by_event_name.row_size";
+ size= sizeof(PFS_single_stat);
+ break;
+ case 69:
+ name= "events_waits_summary_by_host_by_event_name.row_count";
+ size= host_max * wait_class_max;
+ break;
+ case 70:
+ name= "events_waits_summary_by_host_by_event_name.memory";
+ size= host_max * wait_class_max * sizeof(PFS_single_stat);
+ total_memory+= size;
+ break;
+ case 71:
+ name= "(pfs_user).row_size";
+ size= sizeof(PFS_user);
+ break;
+ case 72:
+ name= "(pfs_user).row_count";
+ size= user_max;
+ break;
+ case 73:
+ name= "(pfs_user).memory";
+ size= user_max * sizeof(PFS_user);
+ total_memory+= size;
+ break;
+ case 74:
+ name= "(pfs_host).row_size";
+ size= sizeof(PFS_host);
+ break;
+ case 75:
+ name= "(pfs_host).row_count";
+ size= host_max;
+ break;
+ case 76:
+ name= "(pfs_host).memory";
+ size= host_max * sizeof(PFS_host);
+ total_memory+= size;
+ break;
+ case 77:
name= "(pfs_stage_class).row_size";
size= sizeof(PFS_stage_class);
break;
- case 60:
+ case 78:
name= "(pfs_stage_class).row_count";
size= stage_class_max;
break;
- case 61:
+ case 79:
name= "(pfs_stage_class).memory";
size= stage_class_max * sizeof(PFS_stage_class);
total_memory+= size;
break;
- case 62:
+ case 80:
name= "events_stages_history.row_size";
size= sizeof(PFS_events_stages);
break;
- case 63:
+ case 81:
name= "events_stages_history.row_count";
size= events_stages_history_per_thread * thread_max;
break;
- case 64:
+ case 82:
name= "events_stages_history.memory";
size= events_stages_history_per_thread * thread_max
* sizeof(PFS_events_stages);
total_memory+= size;
break;
- case 65:
+ case 83:
name= "events_stages_history_long.row_size";
size= sizeof(PFS_events_stages);
break;
- case 66:
+ case 84:
name= "events_stages_history_long.row_count";
size= events_stages_history_long_size;
break;
- case 67:
+ case 85:
name= "events_stages_history_long.memory";
size= events_stages_history_long_size * sizeof(PFS_events_stages);
total_memory+= size;
break;
- case 68:
+ case 86:
name= "events_stages_summary_by_thread_by_event_name.row_size";
size= sizeof(PFS_stage_stat);
break;
- case 69:
+ case 87:
name= "events_stages_summary_by_thread_by_event_name.row_count";
size= thread_max * stage_class_max;
break;
- case 70:
+ case 88:
name= "events_stages_summary_by_thread_by_event_name.memory";
size= thread_max * stage_class_max * sizeof(PFS_stage_stat);
total_memory+= size;
break;
- case 71:
+ case 89:
name= "events_stages_summary_global_by_event_name.row_size";
size= sizeof(PFS_stage_stat);
break;
- case 72:
+ case 90:
name= "events_stages_summary_global_by_event_name.row_count";
size= stage_class_max;
break;
- case 73:
+ case 91:
name= "events_stages_summary_global_by_event_name.memory";
size= stage_class_max * sizeof(PFS_stage_stat);
total_memory+= size;
break;
- case 74:
+ case 92:
+ name= "events_stages_summary_by_account_by_event_name.row_size";
+ size= sizeof(PFS_stage_stat);
+ break;
+ case 93:
+ name= "events_stages_summary_by_account_by_event_name.row_count";
+ size= account_max * stage_class_max;
+ break;
+ case 94:
+ name= "events_stages_summary_by_account_by_event_name.memory";
+ size= account_max * stage_class_max * sizeof(PFS_stage_stat);
+ total_memory+= size;
+ break;
+ case 95:
+ name= "events_stages_summary_by_user_by_event_name.row_size";
+ size= sizeof(PFS_stage_stat);
+ break;
+ case 96:
+ name= "events_stages_summary_by_user_by_event_name.row_count";
+ size= user_max * stage_class_max;
+ break;
+ case 97:
+ name= "events_stages_summary_by_user_by_event_name.memory";
+ size= user_max * stage_class_max * sizeof(PFS_stage_stat);
+ total_memory+= size;
+ break;
+ case 98:
+ name= "events_stages_summary_by_host_by_event_name.row_size";
+ size= sizeof(PFS_stage_stat);
+ break;
+ case 99:
+ name= "events_stages_summary_by_host_by_event_name.row_count";
+ size= host_max * stage_class_max;
+ break;
+ case 100:
+ name= "events_stages_summary_by_host_by_event_name.memory";
+ size= host_max * stage_class_max * sizeof(PFS_stage_stat);
+ total_memory+= size;
+ break;
+ case 101:
name= "(pfs_statement_class).row_size";
size= sizeof(PFS_statement_class);
break;
- case 75:
+ case 102:
name= "(pfs_statement_class).row_count";
size= statement_class_max;
break;
- case 76:
+ case 103:
name= "(pfs_statement_class).memory";
size= statement_class_max * sizeof(PFS_statement_class);
total_memory+= size;
break;
- case 77:
+ case 104:
name= "events_statements_history.row_size";
size= sizeof(PFS_events_statements);
break;
- case 78:
+ case 105:
name= "events_statements_history.row_count";
size= events_statements_history_per_thread * thread_max;
break;
- case 79:
+ case 106:
name= "events_statements_history.memory";
size= events_statements_history_per_thread * thread_max
* sizeof(PFS_events_statements);
total_memory+= size;
break;
- case 80:
+ case 107:
name= "events_statements_history_long.row_size";
size= sizeof(PFS_events_statements);
break;
- case 81:
+ case 108:
name= "events_statements_history_long.row_count";
size= events_statements_history_long_size;
break;
- case 82:
+ case 109:
name= "events_statements_history_long.memory";
size= events_statements_history_long_size * sizeof(PFS_events_statements);
total_memory+= size;
break;
- case 83:
+ case 110:
name= "events_statements_summary_by_thread_by_event_name.row_size";
size= sizeof(PFS_statement_stat);
break;
- case 84:
+ case 111:
name= "events_statements_summary_by_thread_by_event_name.row_count";
size= thread_max * statement_class_max;
break;
- case 85:
+ case 112:
name= "events_statements_summary_by_thread_by_event_name.memory";
size= thread_max * statement_class_max * sizeof(PFS_statement_stat);
total_memory+= size;
break;
- case 86:
+ case 113:
name= "events_statements_summary_global_by_event_name.row_size";
size= sizeof(PFS_statement_stat);
break;
- case 87:
+ case 114:
name= "events_statements_summary_global_by_event_name.row_count";
size= statement_class_max;
break;
- case 88:
+ case 115:
name= "events_statements_summary_global_by_event_name.memory";
size= statement_class_max * sizeof(PFS_statement_stat);
total_memory+= size;
break;
- case 89:
+ case 116:
+ name= "events_statements_summary_by_account_by_event_name.row_size";
+ size= sizeof(PFS_statement_stat);
+ break;
+ case 117:
+ name= "events_statements_summary_by_account_by_event_name.row_count";
+ size= account_max * statement_class_max;
+ break;
+ case 118:
+ name= "events_statements_summary_by_account_by_event_name.memory";
+ size= account_max * statement_class_max * sizeof(PFS_statement_stat);
+ total_memory+= size;
+ break;
+ case 119:
+ name= "events_statements_summary_by_user_by_event_name.row_size";
+ size= sizeof(PFS_statement_stat);
+ break;
+ case 120:
+ name= "events_statements_summary_by_user_by_event_name.row_count";
+ size= user_max * statement_class_max;
+ break;
+ case 121:
+ name= "events_statements_summary_by_user_by_event_name.memory";
+ size= user_max * statement_class_max * sizeof(PFS_statement_stat);
+ total_memory+= size;
+ break;
+ case 122:
+ name= "events_statements_summary_by_host_by_event_name.row_size";
+ size= sizeof(PFS_statement_stat);
+ break;
+ case 123:
+ name= "events_statements_summary_by_host_by_event_name.row_count";
+ size= host_max * statement_class_max;
+ break;
+ case 124:
+ name= "events_statements_summary_by_host_by_event_name.memory";
+ size= host_max * statement_class_max * sizeof(PFS_statement_stat);
+ total_memory+= size;
+ break;
+ case 125:
name= "events_statements_current.row_size";
size= sizeof(PFS_events_statements);
break;
- case 90:
+ case 126:
name= "events_statements_current.row_count";
size= thread_max * statement_stack_max;
break;
- case 91:
+ case 127:
name= "events_statements_current.memory";
size= thread_max * statement_stack_max * sizeof(PFS_events_statements);
total_memory+= size;
@@ -1074,7 +1258,7 @@ bool pfs_show_status(handlerton *hton, T
This case must be last,
for aggregation in total_memory.
*/
- case 92:
+ case 128:
name= "performance_schema.memory";
size= total_memory;
/* This will fail if something is not advertised here */
=== modified file 'storage/perfschema/pfs_events_stages.cc'
--- a/storage/perfschema/pfs_events_stages.cc 2011-02-17 18:10:56 +0000
+++ b/storage/perfschema/pfs_events_stages.cc 2011-05-07 00:40:25 +0000
@@ -184,12 +184,12 @@ void reset_events_stages_by_thread()
}
}
-/** Reset table EVENTS_STAGES_SUMMARY_BY_USER_HOST_BY_EVENT_NAME data. */
-void reset_events_stages_by_user_host()
+/** Reset table EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME data. */
+void reset_events_stages_by_account()
{
#ifdef LATER
- PFS_user_host *pfs= user_host_array;
- PFS_user_host *pfs_last= user_host_array + user_host_max;
+ PFS_account *pfs= account_array;
+ PFS_account *pfs_last= account_array + account_max;
for ( ; pfs < pfs_last; pfs++)
{
=== modified file 'storage/perfschema/pfs_events_stages.h'
--- a/storage/perfschema/pfs_events_stages.h 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_events_stages.h 2011-05-07 00:40:25 +0000
@@ -24,7 +24,7 @@
#include "pfs_events.h"
struct PFS_thread;
-struct PFS_user_host;
+struct PFS_account;
struct PFS_user;
struct PFS_host;
@@ -53,11 +53,11 @@ void reset_events_stages_current();
void reset_events_stages_history();
void reset_events_stages_history_long();
void reset_events_stages_by_thread();
-void reset_events_stages_by_user_host();
+void reset_events_stages_by_account();
void reset_events_stages_by_user();
void reset_events_stages_by_host();
void reset_events_stages_global();
-void aggregate_user_host_stages(PFS_user_host *user_host);
+void aggregate_account_stages(PFS_account *account);
void aggregate_user_stages(PFS_user *user);
void aggregate_host_stages(PFS_host *host);
=== modified file 'storage/perfschema/pfs_events_statements.cc'
--- a/storage/perfschema/pfs_events_statements.cc 2011-02-17 18:10:56 +0000
+++ b/storage/perfschema/pfs_events_statements.cc 2011-05-07 00:40:25 +0000
@@ -188,12 +188,12 @@ void reset_events_statements_by_thread()
}
}
-/** Reset table EVENTS_STATEMENTS_SUMMARY_BY_USER_HOST_BY_EVENT_NAME data. */
-void reset_events_statements_by_user_host()
+/** Reset table EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME data. */
+void reset_events_statements_by_account()
{
#ifdef LATER
- PFS_user_host *pfs= user_host_array;
- PFS_user_host *pfs_last= user_host_array + user_host_max;
+ PFS_account *pfs= account_array;
+ PFS_account *pfs_last= account_array + account_max;
for ( ; pfs < pfs_last; pfs++)
{
=== modified file 'storage/perfschema/pfs_events_statements.h'
--- a/storage/perfschema/pfs_events_statements.h 2011-04-04 14:34:42 +0000
+++ b/storage/perfschema/pfs_events_statements.h 2011-05-07 00:40:25 +0000
@@ -25,7 +25,7 @@
#include "pfs_events.h"
struct PFS_thread;
-struct PFS_user_host;
+struct PFS_account;
struct PFS_user;
struct PFS_host;
@@ -108,11 +108,11 @@ void reset_events_statements_current();
void reset_events_statements_history();
void reset_events_statements_history_long();
void reset_events_statements_by_thread();
-void reset_events_statements_by_user_host();
+void reset_events_statements_by_account();
void reset_events_statements_by_user();
void reset_events_statements_by_host();
void reset_events_statements_global();
-void aggregate_user_host_statements(PFS_user_host *user_host);
+void aggregate_account_statements(PFS_account *account);
void aggregate_user_statements(PFS_user *user);
void aggregate_host_statements(PFS_host *host);
=== modified file 'storage/perfschema/pfs_events_waits.cc'
--- a/storage/perfschema/pfs_events_waits.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_events_waits.cc 2011-05-07 00:40:25 +0000
@@ -21,7 +21,11 @@
#include "my_global.h"
#include "my_sys.h"
#include "pfs_global.h"
+#include "pfs_instr_class.h"
#include "pfs_instr.h"
+#include "pfs_user.h"
+#include "pfs_host.h"
+#include "pfs_account.h"
#include "pfs_events_waits.h"
#include "pfs_atomic.h"
#include "m_string.h"
@@ -181,6 +185,45 @@ void reset_events_waits_by_thread()
}
}
+/** Reset table EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME data. */
+void reset_events_waits_by_account()
+{
+ PFS_account *pfs= account_array;
+ PFS_account *pfs_last= account_array + account_max;
+
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ pfs->aggregate_waits();
+ }
+}
+
+/** Reset table EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME data. */
+void reset_events_waits_by_user()
+{
+ PFS_user *pfs= user_array;
+ PFS_user *pfs_last= user_array + user_max;
+
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ pfs->aggregate_waits();
+ }
+}
+
+/** Reset table EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME data. */
+void reset_events_waits_by_host()
+{
+ PFS_host *pfs= host_array;
+ PFS_host *pfs_last= host_array + host_max;
+
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ pfs->aggregate_waits();
+ }
+}
+
/** Reset table EVENTS_WAITS_GLOBAL_BY_EVENT_NAME data. */
void reset_events_waits_global()
{
=== modified file 'storage/perfschema/pfs_events_waits.h'
--- a/storage/perfschema/pfs_events_waits.h 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_events_waits.h 2011-05-07 00:40:25 +0000
@@ -33,6 +33,9 @@ struct PFS_file;
struct PFS_thread;
struct PFS_instr_class;
struct PFS_table_share;
+struct PFS_account;
+struct PFS_user;
+struct PFS_host;
/** Class of a wait event. */
enum events_waits_class
@@ -110,7 +113,13 @@ void reset_events_waits_current();
void reset_events_waits_history();
void reset_events_waits_history_long();
void reset_events_waits_by_thread();
+void reset_events_waits_by_account();
+void reset_events_waits_by_user();
+void reset_events_waits_by_host();
void reset_events_waits_global();
+void aggregate_account_waits(PFS_account *account);
+void aggregate_user_waits(PFS_user *user);
+void aggregate_host_waits(PFS_host *host);
void reset_table_waits_by_table();
void reset_table_io_waits_by_table();
=== added file 'storage/perfschema/pfs_host.cc'
--- a/storage/perfschema/pfs_host.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_host.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,354 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/pfs_host.cc
+ Performance schema host (implementation).
+*/
+
+#include "my_global.h"
+#include "my_sys.h"
+#include "pfs.h"
+#include "pfs_stat.h"
+#include "pfs_instr.h"
+#include "pfs_setup_actor.h"
+#include "pfs_host.h"
+#include "pfs_global.h"
+#include "pfs_instr_class.h"
+
+/**
+ @addtogroup Performance_schema_buffers
+ @{
+*/
+
+ulong host_max;
+ulong host_lost;
+
+PFS_host *host_array= NULL;
+
+static PFS_single_stat *host_instr_class_waits_array= NULL;
+static PFS_stage_stat *host_instr_class_stages_array= NULL;
+static PFS_statement_stat *host_instr_class_statements_array= NULL;
+
+static LF_HASH host_hash;
+static bool host_hash_inited= false;
+
+/**
+ Initialize the host buffers.
+ @param param sizing parameters
+ @return 0 on success
+*/
+int init_host(const PFS_global_param *param)
+{
+ uint index;
+
+ host_max= param->m_host_sizing;
+
+ host_array= NULL;
+ host_instr_class_waits_array= NULL;
+ host_instr_class_stages_array= NULL;
+ host_instr_class_statements_array= NULL;
+ uint waits_sizing= host_max * wait_class_max;
+ uint stages_sizing= host_max * stage_class_max;
+ uint statements_sizing= host_max * statement_class_max;
+
+ if (host_max > 0)
+ {
+ host_array= PFS_MALLOC_ARRAY(host_max, PFS_host,
+ MYF(MY_ZEROFILL));
+ if (unlikely(host_array == NULL))
+ return 1;
+ }
+
+ if (waits_sizing > 0)
+ {
+ host_instr_class_waits_array=
+ PFS_connection_slice::alloc_waits_slice(waits_sizing);
+ if (unlikely(host_instr_class_waits_array == NULL))
+ return 1;
+ }
+
+ if (stages_sizing > 0)
+ {
+ host_instr_class_stages_array=
+ PFS_connection_slice::alloc_stages_slice(stages_sizing);
+ if (unlikely(host_instr_class_stages_array == NULL))
+ return 1;
+ }
+
+ if (statements_sizing > 0)
+ {
+ host_instr_class_statements_array=
+ PFS_connection_slice::alloc_statements_slice(statements_sizing);
+ if (unlikely(host_instr_class_statements_array == NULL))
+ return 1;
+ }
+
+ for (index= 0; index < host_max; index++)
+ {
+ host_array[index].m_instr_class_waits_stats=
+ &host_instr_class_waits_array[index * wait_class_max];
+ host_array[index].m_instr_class_stages_stats=
+ &host_instr_class_stages_array[index * stage_class_max];
+ host_array[index].m_instr_class_statements_stats=
+ &host_instr_class_statements_array[index * statement_class_max];
+ }
+
+ return 0;
+}
+
+/** Cleanup all the host buffers. */
+void cleanup_host(void)
+{
+ pfs_free(host_array);
+ host_array= NULL;
+ pfs_free(host_instr_class_waits_array);
+ host_instr_class_waits_array= NULL;
+ pfs_free(host_instr_class_stages_array);
+ host_instr_class_stages_array= NULL;
+ pfs_free(host_instr_class_statements_array);
+ host_instr_class_statements_array= NULL;
+ host_max= 0;
+}
+
+static uchar *host_hash_get_key(const uchar *entry, size_t *length,
+ my_bool)
+{
+ const PFS_host * const *typed_entry;
+ const PFS_host *host;
+ const void *result;
+ typed_entry= reinterpret_cast<const PFS_host* const *> (entry);
+ DBUG_ASSERT(typed_entry != NULL);
+ host= *typed_entry;
+ DBUG_ASSERT(host != NULL);
+ *length= host->m_key.m_key_length;
+ result= host->m_key.m_hash_key;
+ return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
+}
+
+/**
+ Initialize the host hash.
+ @return 0 on success
+*/
+int init_host_hash(void)
+{
+ if (! host_hash_inited)
+ {
+ lf_hash_init(&host_hash, sizeof(PFS_host*), LF_HASH_UNIQUE,
+ 0, 0, host_hash_get_key, &my_charset_bin);
+ host_hash_inited= true;
+ }
+ return 0;
+}
+
+/** Cleanup the host hash. */
+void cleanup_host_hash(void)
+{
+ if (host_hash_inited)
+ {
+ lf_hash_destroy(&host_hash);
+ host_hash_inited= false;
+ }
+}
+
+static LF_PINS* get_host_hash_pins(PFS_thread *thread)
+{
+ if (unlikely(thread->m_host_hash_pins == NULL))
+ {
+ if (! host_hash_inited)
+ return NULL;
+ thread->m_host_hash_pins= lf_hash_get_pins(&host_hash);
+ }
+ return thread->m_host_hash_pins;
+}
+
+static void set_host_key(PFS_host_key *key,
+ const char *host, uint host_length)
+{
+ DBUG_ASSERT(host_length <= HOSTNAME_LENGTH);
+
+ char *ptr= &key->m_hash_key[0];
+ if (host_length > 0)
+ {
+ memcpy(ptr, host, host_length);
+ ptr+= host_length;
+ }
+ ptr[0]= 0;
+ ptr++;
+ key->m_key_length= ptr - &key->m_hash_key[0];
+}
+
+PFS_host *find_or_create_host(PFS_thread *thread,
+ const char *hostname, uint hostname_length)
+{
+ if (host_max == 0)
+ {
+ host_lost++;
+ return NULL;
+ }
+
+ LF_PINS *pins= get_host_hash_pins(thread);
+ if (unlikely(pins == NULL))
+ {
+ host_lost++;
+ return NULL;
+ }
+
+ PFS_host_key key;
+ set_host_key(&key, hostname, hostname_length);
+
+ PFS_host **entry;
+ uint retry_count= 0;
+ const uint retry_max= 3;
+
+search:
+ entry= reinterpret_cast<PFS_host**>
+ (lf_hash_search(&host_hash, pins,
+ key.m_hash_key, key.m_key_length));
+ if (entry && (entry != MY_ERRPTR))
+ {
+ PFS_host *pfs;
+ pfs= *entry;
+ pfs->inc_refcount();
+ lf_hash_search_unpin(pins);
+ return pfs;
+ }
+
+ PFS_scan scan;
+ uint random= randomized_index(hostname, host_max);
+
+ for (scan.init(random, host_max);
+ scan.has_pass();
+ scan.next_pass())
+ {
+ PFS_host *pfs= host_array + scan.first();
+ PFS_host *pfs_last= host_array + scan.last();
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_free())
+ {
+ if (pfs->m_lock.free_to_dirty())
+ {
+ pfs->m_key= key;
+ if (hostname_length > 0)
+ pfs->m_hostname= &pfs->m_key.m_hash_key[0];
+ else
+ pfs->m_hostname= NULL;
+ pfs->m_hostname_length= hostname_length;
+
+ pfs->init_refcount();
+ pfs->reset_stats();
+ pfs->m_disconnected_count= 0;
+
+ int res;
+ res= lf_hash_insert(&host_hash, pins, &pfs);
+ if (likely(res == 0))
+ {
+ pfs->m_lock.dirty_to_allocated();
+ return pfs;
+ }
+
+ pfs->m_lock.dirty_to_free();
+
+ if (res > 0)
+ {
+ if (++retry_count > retry_max)
+ {
+ host_lost++;
+ return NULL;
+ }
+ goto search;
+ }
+
+ host_lost++;
+ return NULL;
+ }
+ }
+ }
+ }
+
+ host_lost++;
+ return NULL;
+}
+
+void PFS_host::aggregate()
+{
+ aggregate_waits();
+}
+
+void PFS_host::aggregate_waits()
+{
+ /* No parent to aggregate to (for waits only), clean the stats */
+
+ PFS_single_stat *stat= m_instr_class_waits_stats;
+ PFS_single_stat *stat_last= stat + wait_class_max;
+ for ( ; stat < stat_last; stat++)
+ stat->reset();
+}
+
+void PFS_host::release()
+{
+ dec_refcount();
+}
+
+void purge_host(PFS_thread *thread, PFS_host *host)
+{
+ host->aggregate();
+
+ LF_PINS *pins= get_host_hash_pins(thread);
+ if (unlikely(pins == NULL))
+ return;
+
+ PFS_host **entry;
+ entry= reinterpret_cast<PFS_host**>
+ (lf_hash_search(&host_hash, pins,
+ host->m_key.m_hash_key, host->m_key.m_key_length));
+ if (entry && (entry != MY_ERRPTR))
+ {
+ PFS_host *pfs;
+ pfs= *entry;
+ DBUG_ASSERT(pfs == host);
+ if (host->get_refcount() == 0)
+ {
+ lf_hash_delete(&host_hash, pins,
+ host->m_key.m_hash_key, host->m_key.m_key_length);
+ host->m_lock.allocated_to_free();
+ }
+ lf_hash_search_unpin(pins);
+ }
+}
+
+/** Purge non connected hosts, reset stats of connected hosts. */
+void purge_all_host(void)
+{
+ PFS_thread *thread= PFS_thread::get_current_thread();
+ if (unlikely(thread == NULL))
+ return;
+
+ PFS_host *pfs= host_array;
+ PFS_host *pfs_last= host_array + host_max;
+
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ pfs->m_disconnected_count= 0;
+ if (pfs->get_refcount() == 0)
+ purge_host(thread, pfs);
+ }
+ }
+}
+
+/** @} */
=== added file 'storage/perfschema/pfs_host.h'
--- a/storage/perfschema/pfs_host.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_host.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,107 @@
+/* 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 */
+
+#ifndef PFS_HOST_H
+#define PFS_HOST_H
+
+/**
+ @file storage/perfschema/pfs_host.h
+ Performance schema host (declarations).
+*/
+
+#include "pfs_lock.h"
+#include "lf.h"
+#include "pfs_con_slice.h"
+
+struct PFS_global_param;
+struct PFS_thread;
+
+/**
+ @addtogroup Performance_schema_buffers
+ @{
+*/
+
+struct PFS_host_key
+{
+ /**
+ Hash search key.
+ This has to be a string for LF_HASH,
+ the format is "<hostname><0x00>"
+ */
+ char m_hash_key[HOSTNAME_LENGTH + 1];
+ uint m_key_length;
+};
+
+struct PFS_host : PFS_connection_slice
+{
+public:
+ inline void init_refcount(void)
+ {
+ PFS_atomic::store_32(& m_refcount, 1);
+ }
+
+ inline int get_refcount(void)
+ {
+ return PFS_atomic::load_32(& m_refcount);
+ }
+
+ inline void inc_refcount(void)
+ {
+ PFS_atomic::add_32(& m_refcount, 1);
+ }
+
+ inline void dec_refcount(void)
+ {
+ PFS_atomic::add_32(& m_refcount, -1);
+ }
+
+ void aggregate(void);
+ void aggregate_waits(void);
+ void release(void);
+
+ /* Internal lock. */
+ pfs_lock m_lock;
+ PFS_host_key m_key;
+ const char *m_hostname;
+ uint m_hostname_length;
+
+ ulonglong m_disconnected_count;
+
+private:
+ int m_refcount;
+};
+
+int init_host(const PFS_global_param *param);
+void cleanup_host(void);
+int init_host_hash(void);
+void cleanup_host_hash(void);
+
+PFS_host *find_or_create_host(PFS_thread *thread,
+ const char *hostname, uint hostname_length);
+
+void purge_all_host(void);
+
+/* For iterators and show status. */
+
+extern ulong host_max;
+extern ulong host_lost;
+
+/* Exposing the data directly, for iterators. */
+
+extern PFS_host *host_array;
+
+/** @} */
+#endif
+
=== modified file 'storage/perfschema/pfs_instr.cc'
--- a/storage/perfschema/pfs_instr.cc 2011-02-15 14:31:13 +0000
+++ b/storage/perfschema/pfs_instr.cc 2011-05-07 00:40:25 +0000
@@ -25,6 +25,9 @@
#include "pfs.h"
#include "pfs_stat.h"
#include "pfs_instr.h"
+#include "pfs_host.h"
+#include "pfs_user.h"
+#include "pfs_account.h"
#include "pfs_global.h"
#include "pfs_instr_class.h"
@@ -199,7 +202,7 @@ int init_instruments(const PFS_global_pa
thread_statements_history_sizing= param->m_thread_sizing
* events_statements_history_per_thread;
- statement_stack_max= 1; /* No nested statements yet */
+ statement_stack_max= 1;
thread_statements_stack_sizing= param->m_thread_sizing * statement_stack_max;
thread_instr_class_stages_sizing= param->m_thread_sizing
@@ -790,6 +793,9 @@ PFS_thread* create_thread(PFS_thread_cla
pfs->m_table_share_hash_pins= NULL;
pfs->m_setup_actor_hash_pins= NULL;
pfs->m_setup_object_hash_pins= NULL;
+ pfs->m_user_hash_pins= NULL;
+ pfs->m_account_hash_pins= NULL;
+ pfs->m_host_hash_pins= NULL;
pfs->m_username_length= 0;
pfs->m_hostname_length= 0;
@@ -799,6 +805,11 @@ PFS_thread* create_thread(PFS_thread_cla
pfs->m_processlist_state_length= 0;
pfs->m_processlist_info_length= 0;
+ pfs->m_host= NULL;
+ pfs->m_user= NULL;
+ pfs->m_account= NULL;
+ set_thread_account(pfs);
+
PFS_events_waits *child_wait;
for (index= 0; index < WAIT_STACK_SIZE; index++)
{
@@ -932,6 +943,26 @@ PFS_file *sanitize_file(PFS_file *unsafe
void destroy_thread(PFS_thread *pfs)
{
DBUG_ASSERT(pfs != NULL);
+ if (pfs->m_account != NULL)
+ {
+ pfs->m_account->release();
+ pfs->m_account= NULL;
+ DBUG_ASSERT(pfs->m_user == NULL);
+ DBUG_ASSERT(pfs->m_host == NULL);
+ }
+ else
+ {
+ if (pfs->m_user != NULL)
+ {
+ pfs->m_user->release();
+ pfs->m_user= NULL;
+ }
+ if (pfs->m_host != NULL)
+ {
+ pfs->m_host->release();
+ pfs->m_host= NULL;
+ }
+ }
if (pfs->m_filename_hash_pins)
{
lf_hash_put_pins(pfs->m_filename_hash_pins);
@@ -952,10 +983,41 @@ void destroy_thread(PFS_thread *pfs)
lf_hash_put_pins(pfs->m_setup_object_hash_pins);
pfs->m_setup_object_hash_pins= NULL;
}
+ if (pfs->m_user_hash_pins)
+ {
+ lf_hash_put_pins(pfs->m_user_hash_pins);
+ pfs->m_user_hash_pins= NULL;
+ }
+ if (pfs->m_account_hash_pins)
+ {
+ lf_hash_put_pins(pfs->m_account_hash_pins);
+ pfs->m_account_hash_pins= NULL;
+ }
+ if (pfs->m_host_hash_pins)
+ {
+ lf_hash_put_pins(pfs->m_host_hash_pins);
+ pfs->m_host_hash_pins= NULL;
+ }
pfs->m_lock.allocated_to_free();
}
/**
+ Get the hash pins for @filename_hash.
+ @param thread The running thread.
+ @returns The LF_HASH pins for the thread.
+*/
+LF_PINS* get_filename_hash_pins(PFS_thread *thread)
+{
+ if (unlikely(thread->m_filename_hash_pins == NULL))
+ {
+ if (! filename_hash_inited)
+ return NULL;
+ thread->m_filename_hash_pins= lf_hash_get_pins(&filename_hash);
+ }
+ return thread->m_filename_hash_pins;
+}
+
+/**
Find or create instrumentation for a file instance by file name.
@param thread the executing instrumented thread
@param klass the file class
@@ -970,23 +1032,13 @@ find_or_create_file(PFS_thread *thread,
PFS_file *pfs;
PFS_scan scan;
- if (! filename_hash_inited)
+ LF_PINS *pins= get_filename_hash_pins(thread);
+ if (unlikely(pins == NULL))
{
- /* File instrumentation can be turned off. */
file_lost++;
return NULL;
}
- if (unlikely(thread->m_filename_hash_pins == NULL))
- {
- thread->m_filename_hash_pins= lf_hash_get_pins(&filename_hash);
- if (unlikely(thread->m_filename_hash_pins == NULL))
- {
- file_lost++;
- return NULL;
- }
- }
-
char safe_buffer[FN_REFLEN];
const char *safe_filename;
@@ -1072,13 +1124,13 @@ find_or_create_file(PFS_thread *thread,
const uint retry_max= 3;
search:
entry= reinterpret_cast<PFS_file**>
- (lf_hash_search(&filename_hash, thread->m_filename_hash_pins,
+ (lf_hash_search(&filename_hash, pins,
normalized_filename, normalized_length));
if (entry && (entry != MY_ERRPTR))
{
pfs= *entry;
pfs->m_file_stat.m_open_count++;
- lf_hash_search_unpin(thread->m_filename_hash_pins);
+ lf_hash_search_unpin(pins);
return pfs;
}
@@ -1106,7 +1158,7 @@ search:
pfs->m_file_stat.m_io_stat.reset();
int res;
- res= lf_hash_insert(&filename_hash, thread->m_filename_hash_pins,
+ res= lf_hash_insert(&filename_hash, pins,
&pfs);
if (likely(res == 0))
{
@@ -1160,7 +1212,6 @@ void release_file(PFS_file *pfs)
void destroy_file(PFS_thread *thread, PFS_file *pfs)
{
DBUG_ASSERT(thread != NULL);
- DBUG_ASSERT(thread->m_filename_hash_pins != NULL);
DBUG_ASSERT(pfs != NULL);
PFS_file_class *klass= pfs->m_class;
@@ -1173,7 +1224,13 @@ void destroy_file(PFS_thread *thread, PF
klass->m_file_stat.m_io_stat.aggregate(& pfs->m_file_stat.m_io_stat);
pfs->m_file_stat.m_io_stat.reset();
- lf_hash_delete(&filename_hash, thread->m_filename_hash_pins,
+ if (klass->is_singleton())
+ klass->m_singleton= NULL;
+
+ LF_PINS *pins= get_filename_hash_pins(thread);
+ DBUG_ASSERT(pins != NULL);
+
+ lf_hash_delete(&filename_hash, pins,
pfs->m_filename, pfs->m_filename_length);
if (klass->is_singleton())
klass->m_singleton= NULL;
@@ -1489,16 +1546,92 @@ void aggregate_all_statements(PFS_statem
}
}
+void aggregate_thread_stats(PFS_thread *thread)
+{
+ if (likely(thread->m_account != NULL))
+ {
+ thread->m_account->m_disconnected_count++;
+ }
+ else
+ {
+ if (thread->m_user != NULL)
+ thread->m_user->m_disconnected_count++;
+
+ if (thread->m_host != NULL)
+ thread->m_host->m_disconnected_count++;
+ }
+}
+
void aggregate_thread(PFS_thread *thread)
{
aggregate_thread_waits(thread);
aggregate_thread_stages(thread);
aggregate_thread_statements(thread);
+ aggregate_thread_stats(thread);
}
-
void aggregate_thread_waits(PFS_thread *thread)
{
+ if (likely(thread->m_account != NULL))
+ {
+ DBUG_ASSERT(thread->m_user == NULL);
+ DBUG_ASSERT(thread->m_host == NULL);
+ DBUG_ASSERT(thread->m_account->get_refcount() > 0);
+
+ /*
+ Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME
+ to EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME.
+ */
+ aggregate_all_event_names(thread->m_instr_class_waits_stats,
+ thread->m_account->m_instr_class_waits_stats);
+
+ return;
+ }
+
+ if ((thread->m_user != NULL) && (thread->m_host != NULL))
+ {
+ DBUG_ASSERT(thread->m_user->get_refcount() > 0);
+ DBUG_ASSERT(thread->m_host->get_refcount() > 0);
+
+ /*
+ Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME to:
+ - EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME
+ - EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME
+ in parallel.
+ */
+ aggregate_all_event_names(thread->m_instr_class_waits_stats,
+ thread->m_user->m_instr_class_waits_stats,
+ thread->m_host->m_instr_class_waits_stats);
+ return;
+ }
+
+ if (thread->m_user != NULL)
+ {
+ DBUG_ASSERT(thread->m_user->get_refcount() > 0);
+
+ /*
+ Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME
+ to EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME, directly.
+ */
+ aggregate_all_event_names(thread->m_instr_class_waits_stats,
+ thread->m_user->m_instr_class_waits_stats);
+ return;
+ }
+
+ if (thread->m_host != NULL)
+ {
+ DBUG_ASSERT(thread->m_host->get_refcount() > 0);
+
+ /*
+ Aggregate EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME
+ to EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME, directly.
+ */
+ aggregate_all_event_names(thread->m_instr_class_waits_stats,
+ thread->m_host->m_instr_class_waits_stats);
+ return;
+ }
+
+ /* Orphan thread, clean the stats */
PFS_single_stat *stat= thread->m_instr_class_waits_stats;
PFS_single_stat *stat_last= stat + wait_class_max;
for ( ; stat < stat_last; stat++)
@@ -1525,4 +1658,48 @@ void aggregate_thread_statements(PFS_thr
global_instr_class_statements_array);
}
+void clear_thread_account(PFS_thread *thread)
+{
+ if (thread->m_account != NULL)
+ {
+ thread->m_account->release();
+ thread->m_account= NULL;
+ }
+
+ if (thread->m_user != NULL)
+ {
+ thread->m_user->release();
+ thread->m_user= NULL;
+ }
+
+ if (thread->m_host != NULL)
+ {
+ thread->m_host->release();
+ thread->m_host= NULL;
+ }
+}
+
+void set_thread_account(PFS_thread *thread)
+{
+ DBUG_ASSERT(thread->m_account == NULL);
+ DBUG_ASSERT(thread->m_user == NULL);
+ DBUG_ASSERT(thread->m_host == NULL);
+
+ thread->m_account= find_or_create_account(thread,
+ thread->m_username,
+ thread->m_username_length,
+ thread->m_hostname,
+ thread->m_hostname_length);
+
+ if ((thread->m_account == NULL) && (thread->m_username_length > 0))
+ thread->m_user= find_or_create_user(thread,
+ thread->m_username,
+ thread->m_username_length);
+
+ if ((thread->m_account == NULL) && (thread->m_hostname_length > 0))
+ thread->m_host= find_or_create_host(thread,
+ thread->m_hostname,
+ thread->m_hostname_length);
+}
+
/** @} */
=== modified file 'storage/perfschema/pfs_instr.h'
--- a/storage/perfschema/pfs_instr.h 2011-04-04 14:34:42 +0000
+++ b/storage/perfschema/pfs_instr.h 2011-05-07 00:40:25 +0000
@@ -44,6 +44,9 @@ struct PFS_thread_class;
*/
struct PFS_thread;
+struct PFS_host;
+struct PFS_user;
+struct PFS_account;
/** Base structure for wait instruments. */
struct PFS_instr
@@ -288,6 +291,12 @@ struct PFS_thread : PFS_connection_slice
LF_PINS *m_setup_actor_hash_pins;
/** Pins for setup_object_hash. */
LF_PINS *m_setup_object_hash_pins;
+ /** Pins for host_hash. */
+ LF_PINS *m_host_hash_pins;
+ /** Pins for user_hash. */
+ LF_PINS *m_user_hash_pins;
+ /** Pins for account_hash. */
+ LF_PINS *m_account_hash_pins;
/** Event ID counter */
ulonglong m_event_id;
/** Thread instrumentation flag. */
@@ -395,6 +404,10 @@ struct PFS_thread : PFS_connection_slice
/** Size of @c m_events_statements_stack. */
uint m_events_statements_count;
PFS_events_statements *m_statement_stack;
+
+ PFS_host *m_host;
+ PFS_user *m_user;
+ PFS_account *m_account;
};
extern PFS_single_stat *global_instr_class_waits_array;
@@ -484,6 +497,8 @@ void aggregate_thread(PFS_thread *thread
void aggregate_thread_waits(PFS_thread *thread);
void aggregate_thread_stages(PFS_thread *thread);
void aggregate_thread_statements(PFS_thread *thread);
+void clear_thread_account(PFS_thread *thread);
+void set_thread_account(PFS_thread *thread);
/** @} */
#endif
=== modified file 'storage/perfschema/pfs_instr_class.cc'
--- a/storage/perfschema/pfs_instr_class.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_instr_class.cc 2011-05-07 00:40:25 +0000
@@ -92,9 +92,9 @@ ulong table_share_max= 0;
/** Number of table share lost. @sa table_share_array */
ulong table_share_lost= 0;
-static PFS_mutex_class *mutex_class_array= NULL;
-static PFS_rwlock_class *rwlock_class_array= NULL;
-static PFS_cond_class *cond_class_array= NULL;
+PFS_mutex_class *mutex_class_array= NULL;
+PFS_rwlock_class *rwlock_class_array= NULL;
+PFS_cond_class *cond_class_array= NULL;
/**
Current number or elements in thread_class_array.
@@ -139,7 +139,7 @@ C_MODE_END
static volatile uint32 file_class_dirty_count= 0;
static volatile uint32 file_class_allocated_count= 0;
-static PFS_file_class *file_class_array= NULL;
+PFS_file_class *file_class_array= NULL;
static volatile uint32 stage_class_dirty_count= 0;
static volatile uint32 stage_class_allocated_count= 0;
=== modified file 'storage/perfschema/pfs_instr_class.h'
--- a/storage/perfschema/pfs_instr_class.h 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_instr_class.h 2011-05-07 00:40:25 +0000
@@ -390,6 +390,13 @@ extern ulong statement_class_max;
extern ulong statement_class_lost;
extern ulong table_share_max;
extern ulong table_share_lost;
+
+/* Exposing the data directly, for iterators. */
+
+extern PFS_mutex_class *mutex_class_array;
+extern PFS_rwlock_class *rwlock_class_array;
+extern PFS_cond_class *cond_class_array;
+extern PFS_file_class *file_class_array;
extern PFS_table_share *table_share_array;
void reset_file_class_io();
=== modified file 'storage/perfschema/pfs_server.cc'
--- a/storage/perfschema/pfs_server.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_server.cc 2011-05-07 00:40:25 +0000
@@ -32,6 +32,9 @@
#include "pfs_timer.h"
#include "pfs_setup_actor.h"
#include "pfs_setup_object.h"
+#include "pfs_host.h"
+#include "pfs_user.h"
+#include "pfs_account.h"
#include "pfs_defaults.h"
PFS_global_param pfs_param;
@@ -85,7 +88,13 @@ initialize_performance_schema(const PFS_
init_setup_actor(param) ||
init_setup_actor_hash() ||
init_setup_object(param) ||
- init_setup_object_hash())
+ init_setup_object_hash() ||
+ init_host(param) ||
+ init_host_hash() ||
+ init_user(param) ||
+ init_user_hash() ||
+ init_account(param) ||
+ init_account_hash())
{
/*
The performance schema initialization failed.
@@ -137,6 +146,12 @@ static void cleanup_performance_schema(v
cleanup_setup_actor_hash();
cleanup_setup_object();
cleanup_setup_object_hash();
+ cleanup_host();
+ cleanup_host_hash();
+ cleanup_user();
+ cleanup_user_hash();
+ cleanup_account();
+ cleanup_account_hash();
PFS_atomic::cleanup();
}
@@ -156,3 +171,4 @@ void shutdown_performance_schema(void)
}
}
+
=== modified file 'storage/perfschema/pfs_server.h'
--- a/storage/perfschema/pfs_server.h 2011-04-04 14:34:42 +0000
+++ b/storage/perfschema/pfs_server.h 2011-05-07 00:40:25 +0000
@@ -72,6 +72,15 @@
#ifndef PFS_MAX_SETUP_OBJECT
#define PFS_MAX_SETUP_OBJECT 100
#endif
+#ifndef PFS_MAX_HOST
+ #define PFS_MAX_HOST 100
+#endif
+#ifndef PFS_MAX_USER
+ #define PFS_MAX_USER 100
+#endif
+#ifndef PFS_MAX_ACCOUNT
+ #define PFS_MAX_ACCOUNT 100
+#endif
#ifndef PFS_MAX_STAGE_CLASS
#define PFS_MAX_STAGE_CLASS 100
#endif
@@ -169,6 +178,12 @@ struct PFS_global_param
ulong m_setup_actor_sizing;
/** Maximum number of rows in table SETUP_OBJECTS. */
ulong m_setup_object_sizing;
+ /** Maximum number of rows in table HOSTS. */
+ ulong m_host_sizing;
+ /** Maximum number of rows in table USERS. */
+ ulong m_user_sizing;
+ /** Maximum number of rows in table ACCOUNTS. */
+ ulong m_account_sizing;
/**
Maximum number of instrumented stage classes.
@sa stage_class_lost.
=== modified file 'storage/perfschema/pfs_setup_actor.cc'
--- a/storage/perfschema/pfs_setup_actor.cc 2011-04-04 14:34:42 +0000
+++ b/storage/perfschema/pfs_setup_actor.cc 2011-05-07 00:40:25 +0000
@@ -119,10 +119,12 @@ void cleanup_setup_actor_hash(void)
static LF_PINS* get_setup_actor_hash_pins(PFS_thread *thread)
{
- if (! setup_actor_hash_inited)
- return NULL;
if (unlikely(thread->m_setup_actor_hash_pins == NULL))
+ {
+ if (! setup_actor_hash_inited)
+ return NULL;
thread->m_setup_actor_hash_pins= lf_hash_get_pins(&setup_actor_hash);
+ }
return thread->m_setup_actor_hash_pins;
}
=== modified file 'storage/perfschema/pfs_setup_object.cc'
--- a/storage/perfschema/pfs_setup_object.cc 2010-09-24 21:04:59 +0000
+++ b/storage/perfschema/pfs_setup_object.cc 2011-05-07 00:40:25 +0000
@@ -114,10 +114,12 @@ void cleanup_setup_object_hash(void)
static LF_PINS* get_setup_object_hash_pins(PFS_thread *thread)
{
- if (! setup_object_hash_inited)
- return NULL;
if (unlikely(thread->m_setup_object_hash_pins == NULL))
+ {
+ if (! setup_object_hash_inited)
+ return NULL;
thread->m_setup_object_hash_pins= lf_hash_get_pins(&setup_object_hash);
+ }
return thread->m_setup_object_hash_pins;
}
=== modified file 'storage/perfschema/pfs_stat.h'
--- a/storage/perfschema/pfs_stat.h 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_stat.h 2011-05-07 00:40:25 +0000
@@ -428,6 +428,28 @@ struct PFS_table_stat
}
};
+struct PFS_connection_stat
+{
+ PFS_connection_stat()
+ : m_current_connections(0),
+ m_total_connections(0)
+ {}
+
+ ulonglong m_current_connections;
+ ulonglong m_total_connections;
+
+ inline void aggregate_active(ulonglong active)
+ {
+ m_current_connections+= active;
+ m_total_connections+= active;
+ }
+
+ inline void aggregate_disconnected(ulonglong disconnected)
+ {
+ m_total_connections+= disconnected;
+ }
+};
+
/** @} */
#endif
=== added file 'storage/perfschema/pfs_user.cc'
--- a/storage/perfschema/pfs_user.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_user.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,363 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/pfs_user.cc
+ Performance schema user (implementation).
+*/
+
+#include "my_global.h"
+#include "my_sys.h"
+#include "pfs.h"
+#include "pfs_stat.h"
+#include "pfs_instr.h"
+#include "pfs_setup_actor.h"
+#include "pfs_user.h"
+#include "pfs_global.h"
+#include "pfs_instr_class.h"
+
+/**
+ @addtogroup Performance_schema_buffers
+ @{
+*/
+
+ulong user_max;
+ulong user_lost;
+
+PFS_user *user_array= NULL;
+
+static PFS_single_stat *user_instr_class_waits_array= NULL;
+static PFS_stage_stat *user_instr_class_stages_array= NULL;
+static PFS_statement_stat *user_instr_class_statements_array= NULL;
+
+static LF_HASH user_hash;
+static bool user_hash_inited= false;
+
+/**
+ Initialize the user buffers.
+ @param param sizing parameters
+ @return 0 on success
+*/
+int init_user(const PFS_global_param *param)
+{
+ uint index;
+
+ user_max= param->m_user_sizing;
+
+ user_array= NULL;
+ user_instr_class_waits_array= NULL;
+ user_instr_class_stages_array= NULL;
+ user_instr_class_statements_array= NULL;
+ uint waits_sizing= user_max * wait_class_max;
+ uint stages_sizing= user_max * stage_class_max;
+ uint statements_sizing= user_max * statement_class_max;
+
+ if (user_max > 0)
+ {
+ user_array= PFS_MALLOC_ARRAY(user_max, PFS_user,
+ MYF(MY_ZEROFILL));
+ if (unlikely(user_array == NULL))
+ return 1;
+ }
+
+ if (waits_sizing > 0)
+ {
+ user_instr_class_waits_array=
+ PFS_connection_slice::alloc_waits_slice(waits_sizing);
+ if (unlikely(user_instr_class_waits_array == NULL))
+ return 1;
+ }
+
+ if (stages_sizing > 0)
+ {
+ user_instr_class_stages_array=
+ PFS_connection_slice::alloc_stages_slice(stages_sizing);
+ if (unlikely(user_instr_class_stages_array == NULL))
+ return 1;
+ }
+
+ if (statements_sizing > 0)
+ {
+ user_instr_class_statements_array=
+ PFS_connection_slice::alloc_statements_slice(statements_sizing);
+ if (unlikely(user_instr_class_statements_array == NULL))
+ return 1;
+ }
+
+ for (index= 0; index < user_max; index++)
+ {
+ user_array[index].m_instr_class_waits_stats=
+ &user_instr_class_waits_array[index * wait_class_max];
+ user_array[index].m_instr_class_stages_stats=
+ &user_instr_class_stages_array[index * stage_class_max];
+ user_array[index].m_instr_class_statements_stats=
+ &user_instr_class_statements_array[index * statement_class_max];
+ }
+
+ return 0;
+}
+
+/** Cleanup all the user buffers. */
+void cleanup_user(void)
+{
+ pfs_free(user_array);
+ user_array= NULL;
+ pfs_free(user_instr_class_waits_array);
+ user_instr_class_waits_array= NULL;
+ pfs_free(user_instr_class_stages_array);
+ user_instr_class_stages_array= NULL;
+ pfs_free(user_instr_class_statements_array);
+ user_instr_class_statements_array= NULL;
+ user_max= 0;
+}
+
+static uchar *user_hash_get_key(const uchar *entry, size_t *length,
+ my_bool)
+{
+ const PFS_user * const *typed_entry;
+ const PFS_user *user;
+ const void *result;
+ typed_entry= reinterpret_cast<const PFS_user* const *> (entry);
+ DBUG_ASSERT(typed_entry != NULL);
+ user= *typed_entry;
+ DBUG_ASSERT(user != NULL);
+ *length= user->m_key.m_key_length;
+ result= user->m_key.m_hash_key;
+ return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
+}
+
+/**
+ Initialize the user hash.
+ @return 0 on success
+*/
+int init_user_hash(void)
+{
+ if (! user_hash_inited)
+ {
+ lf_hash_init(&user_hash, sizeof(PFS_user*), LF_HASH_UNIQUE,
+ 0, 0, user_hash_get_key, &my_charset_bin);
+ user_hash_inited= true;
+ }
+ return 0;
+}
+
+/** Cleanup the user hash. */
+void cleanup_user_hash(void)
+{
+ if (user_hash_inited)
+ {
+ lf_hash_destroy(&user_hash);
+ user_hash_inited= false;
+ }
+}
+
+static LF_PINS* get_user_hash_pins(PFS_thread *thread)
+{
+ if (unlikely(thread->m_user_hash_pins == NULL))
+ {
+ if (! user_hash_inited)
+ return NULL;
+ thread->m_user_hash_pins= lf_hash_get_pins(&user_hash);
+ }
+ return thread->m_user_hash_pins;
+}
+
+static void set_user_key(PFS_user_key *key,
+ const char *user, uint user_length)
+{
+ DBUG_ASSERT(user_length <= USERNAME_LENGTH);
+
+ char *ptr= &key->m_hash_key[0];
+ if (user_length > 0)
+ {
+ memcpy(ptr, user, user_length);
+ ptr+= user_length;
+ }
+ ptr[0]= 0;
+ ptr++;
+ key->m_key_length= ptr - &key->m_hash_key[0];
+}
+
+PFS_user *
+find_or_create_user(PFS_thread *thread,
+ const char *username, uint username_length)
+{
+ if (user_max == 0)
+ {
+ user_lost++;
+ return NULL;
+ }
+
+ LF_PINS *pins= get_user_hash_pins(thread);
+ if (unlikely(pins == NULL))
+ {
+ user_lost++;
+ return NULL;
+ }
+
+ PFS_user_key key;
+ set_user_key(&key, username, username_length);
+
+ PFS_user **entry;
+ uint retry_count= 0;
+ const uint retry_max= 3;
+
+search:
+ entry= reinterpret_cast<PFS_user**>
+ (lf_hash_search(&user_hash, pins,
+ key.m_hash_key, key.m_key_length));
+ if (entry && (entry != MY_ERRPTR))
+ {
+ PFS_user *pfs;
+ pfs= *entry;
+ pfs->inc_refcount();
+ lf_hash_search_unpin(pins);
+ return pfs;
+ }
+
+ PFS_scan scan;
+ uint random= randomized_index(username, user_max);
+
+ for (scan.init(random, user_max);
+ scan.has_pass();
+ scan.next_pass())
+ {
+ PFS_user *pfs= user_array + scan.first();
+ PFS_user *pfs_last= user_array + scan.last();
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_free())
+ {
+ if (pfs->m_lock.free_to_dirty())
+ {
+ pfs->m_key= key;
+ if (username_length > 0)
+ pfs->m_username= &pfs->m_key.m_hash_key[0];
+ else
+ pfs->m_username= NULL;
+ pfs->m_username_length= username_length;
+
+ pfs->init_refcount();
+ pfs->reset_stats();
+ pfs->m_disconnected_count= 0;
+
+ int res;
+ res= lf_hash_insert(&user_hash, pins, &pfs);
+ if (likely(res == 0))
+ {
+ pfs->m_lock.dirty_to_allocated();
+ return pfs;
+ }
+
+ pfs->m_lock.dirty_to_free();
+
+ if (res > 0)
+ {
+ if (++retry_count > retry_max)
+ {
+ user_lost++;
+ return NULL;
+ }
+ goto search;
+ }
+
+ user_lost++;
+ return NULL;
+ }
+ }
+ }
+ }
+
+ user_lost++;
+ return NULL;
+}
+
+void PFS_user::aggregate()
+{
+ aggregate_waits();
+}
+
+void PFS_user::aggregate_waits()
+{
+ /* No parent to aggregate to, clean the stats */
+
+ PFS_single_stat *stat= m_instr_class_waits_stats;
+ PFS_single_stat *stat_last= stat + wait_class_max;
+ for ( ; stat < stat_last; stat++)
+ stat->reset();
+}
+
+void PFS_user::release()
+{
+ dec_refcount();
+}
+
+PFS_user *sanitize_user(PFS_user *unsafe)
+{
+ if ((&user_array[0] <= unsafe) &&
+ (unsafe < &user_array[user_max]))
+ return unsafe;
+ return NULL;
+}
+
+void purge_user(PFS_thread *thread, PFS_user *user)
+{
+ user->aggregate();
+
+ LF_PINS *pins= get_user_hash_pins(thread);
+ if (unlikely(pins == NULL))
+ return;
+
+ PFS_user **entry;
+ entry= reinterpret_cast<PFS_user**>
+ (lf_hash_search(&user_hash, pins,
+ user->m_key.m_hash_key, user->m_key.m_key_length));
+ if (entry && (entry != MY_ERRPTR))
+ {
+ PFS_user *pfs;
+ pfs= *entry;
+ DBUG_ASSERT(pfs == user);
+ if (user->get_refcount() == 0)
+ {
+ lf_hash_delete(&user_hash, pins,
+ user->m_key.m_hash_key, user->m_key.m_key_length);
+ user->m_lock.allocated_to_free();
+ }
+ lf_hash_search_unpin(pins);
+ }
+}
+
+/** Purge non connected users, reset stats of connected users. */
+void purge_all_user(void)
+{
+ PFS_thread *thread= PFS_thread::get_current_thread();
+ if (unlikely(thread == NULL))
+ return;
+
+ PFS_user *pfs= user_array;
+ PFS_user *pfs_last= user_array + user_max;
+
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ pfs->m_disconnected_count= 0;
+ if (pfs->get_refcount() == 0)
+ purge_user(thread, pfs);
+ }
+ }
+}
+
+/** @} */
=== added file 'storage/perfschema/pfs_user.h'
--- a/storage/perfschema/pfs_user.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_user.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,110 @@
+/* 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 */
+
+#ifndef PFS_USER_H
+#define PFS_USER_H
+
+/**
+ @file storage/perfschema/pfs_user.h
+ Performance schema user (declarations).
+*/
+
+#include "pfs_lock.h"
+#include "lf.h"
+#include "pfs_con_slice.h"
+
+struct PFS_global_param;
+struct PFS_thread;
+
+/**
+ @addtogroup Performance_schema_buffers
+ @{
+*/
+
+struct PFS_user_key
+{
+ /**
+ Hash search key.
+ This has to be a string for LF_HASH,
+ the format is "<username><0x00>"
+ */
+ char m_hash_key[USERNAME_LENGTH + 1];
+ uint m_key_length;
+};
+
+struct PFS_user : public PFS_connection_slice
+{
+public:
+ inline void init_refcount(void)
+ {
+ PFS_atomic::store_32(& m_refcount, 1);
+ }
+
+ inline int get_refcount(void)
+ {
+ return PFS_atomic::load_32(& m_refcount);
+ }
+
+ inline void inc_refcount(void)
+ {
+ PFS_atomic::add_32(& m_refcount, 1);
+ }
+
+ inline void dec_refcount(void)
+ {
+ PFS_atomic::add_32(& m_refcount, -1);
+ }
+
+ void aggregate(void);
+ void aggregate_waits(void);
+ void release(void);
+
+ /** Internal lock. */
+ pfs_lock m_lock;
+ PFS_user_key m_key;
+ const char *m_username;
+ uint m_username_length;
+
+ ulonglong m_disconnected_count;
+
+private:
+ int m_refcount;
+};
+
+int init_user(const PFS_global_param *param);
+void cleanup_user(void);
+int init_user_hash(void);
+void cleanup_user_hash(void);
+
+PFS_user *
+find_or_create_user(PFS_thread *thread,
+ const char *username, uint username_length);
+
+PFS_user *sanitize_user(PFS_user *unsafe);
+void purge_all_user(void);
+
+
+/* For iterators and show status. */
+
+extern ulong user_max;
+extern ulong user_lost;
+
+/* Exposing the data directly, for iterators. */
+
+extern PFS_user *user_array;
+
+/** @} */
+#endif
+
=== modified file 'storage/perfschema/pfs_visitor.cc'
--- a/storage/perfschema/pfs_visitor.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_visitor.cc 2011-05-07 00:40:25 +0000
@@ -17,6 +17,9 @@
#include "my_sys.h"
#include "pfs_visitor.h"
#include "pfs_instr.h"
+#include "pfs_user.h"
+#include "pfs_host.h"
+#include "pfs_account.h"
/**
@file storage/perfschema/pfs_visitor.cc
@@ -28,13 +31,47 @@
@{
*/
-void PFS_connection_iterator::visit_global(bool with_threads,
+void PFS_connection_iterator::visit_global(bool with_hosts, bool with_users,
+ bool with_accounts, bool with_threads,
PFS_connection_visitor *visitor)
{
DBUG_ASSERT(visitor != NULL);
visitor->visit_global();
+ if (with_hosts)
+ {
+ PFS_host *pfs= host_array;
+ PFS_host *pfs_last= pfs + host_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ visitor->visit_host(pfs);
+ }
+ }
+
+ if (with_users)
+ {
+ PFS_user *pfs= user_array;
+ PFS_user *pfs_last= pfs + user_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ visitor->visit_user(pfs);
+ }
+ }
+
+ if (with_accounts)
+ {
+ PFS_account *pfs= account_array;
+ PFS_account *pfs_last= pfs + account_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ visitor->visit_account(pfs);
+ }
+ }
+
if (with_threads)
{
PFS_thread *pfs= thread_array;
@@ -47,6 +84,266 @@ void PFS_connection_iterator::visit_glob
}
}
+void PFS_connection_iterator::visit_host(PFS_host *host,
+ bool with_accounts, bool with_threads,
+ PFS_connection_visitor *visitor)
+{
+ DBUG_ASSERT(visitor != NULL);
+
+ visitor->visit_host(host);
+
+ if (with_accounts)
+ {
+ PFS_account *pfs= account_array;
+ PFS_account *pfs_last= pfs + account_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if ((pfs->m_host == host) && pfs->m_lock.is_populated())
+ {
+ visitor->visit_account(pfs);
+ }
+ }
+ }
+
+ if (with_threads)
+ {
+ PFS_thread *pfs= thread_array;
+ PFS_thread *pfs_last= pfs + thread_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ PFS_account *safe_account= sanitize_account(pfs->m_account);
+ if ((safe_account != NULL) && (safe_account->m_host == host))
+ {
+ /*
+ If the thread belongs to a known user@host that belongs to this host,
+ process it.
+ */
+ visitor->visit_thread(pfs);
+ }
+ else if (pfs->m_host == host)
+ {
+ /*
+ If the thread belongs to a 'lost' user@host that belong to this host,
+ process it.
+ */
+ visitor->visit_thread(pfs);
+ }
+ }
+ }
+ }
+}
+
+void PFS_connection_iterator::visit_user(PFS_user *user,
+ bool with_accounts, bool with_threads,
+ PFS_connection_visitor *visitor)
+{
+ DBUG_ASSERT(visitor != NULL);
+
+ visitor->visit_user(user);
+
+ if (with_accounts)
+ {
+ PFS_account *pfs= account_array;
+ PFS_account *pfs_last= pfs + account_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if ((pfs->m_user == user) && pfs->m_lock.is_populated())
+ {
+ visitor->visit_account(pfs);
+ }
+ }
+ }
+
+ if (with_threads)
+ {
+ PFS_thread *pfs= thread_array;
+ PFS_thread *pfs_last= pfs + thread_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ PFS_account *safe_account= sanitize_account(pfs->m_account);
+ if ((safe_account != NULL) && (safe_account->m_user == user))
+ {
+ /*
+ If the thread belongs to a known user@host that belongs to this user,
+ process it.
+ */
+ visitor->visit_thread(pfs);
+ }
+ else if (pfs->m_user == user)
+ {
+ /*
+ If the thread belongs to a 'lost' user@host that belong to this user,
+ process it.
+ */
+ visitor->visit_thread(pfs);
+ }
+ }
+ }
+ }
+}
+
+void PFS_connection_iterator::visit_account(PFS_account *account,
+ bool with_threads,
+ PFS_connection_visitor *visitor)
+{
+ DBUG_ASSERT(visitor != NULL);
+
+ visitor->visit_account(account);
+
+ if (with_threads)
+ {
+ PFS_thread *pfs= thread_array;
+ PFS_thread *pfs_last= pfs + thread_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if ((pfs->m_account == account) && pfs->m_lock.is_populated())
+ {
+ visitor->visit_thread(pfs);
+ }
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all(PFS_instance_visitor *visitor)
+{
+ visit_all_mutex(visitor);
+ visit_all_rwlock(visitor);
+ visit_all_cond(visitor);
+ visit_all_file(visitor);
+}
+
+void PFS_instance_iterator::visit_all_mutex(PFS_instance_visitor *visitor)
+{
+ visit_all_mutex_classes(visitor);
+ visit_all_mutex_instances(visitor);
+}
+
+void PFS_instance_iterator::visit_all_mutex_classes(PFS_instance_visitor *visitor)
+{
+ PFS_mutex_class *pfs= mutex_class_array;
+ PFS_mutex_class *pfs_last= pfs + mutex_class_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_name_length != 0)
+ {
+ visitor->visit_mutex_class(pfs);
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all_mutex_instances(PFS_instance_visitor *visitor)
+{
+ PFS_mutex *pfs= mutex_array;
+ PFS_mutex *pfs_last= pfs + mutex_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ visitor->visit_mutex(pfs);
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all_rwlock(PFS_instance_visitor *visitor)
+{
+ visit_all_rwlock_classes(visitor);
+ visit_all_rwlock_instances(visitor);
+}
+
+void PFS_instance_iterator::visit_all_rwlock_classes(PFS_instance_visitor *visitor)
+{
+ PFS_rwlock_class *pfs= rwlock_class_array;
+ PFS_rwlock_class *pfs_last= pfs + rwlock_class_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_name_length != 0)
+ {
+ visitor->visit_rwlock_class(pfs);
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all_rwlock_instances(PFS_instance_visitor *visitor)
+{
+ PFS_rwlock *pfs= rwlock_array;
+ PFS_rwlock *pfs_last= pfs + rwlock_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ visitor->visit_rwlock(pfs);
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all_cond(PFS_instance_visitor *visitor)
+{
+ visit_all_cond_classes(visitor);
+ visit_all_cond_instances(visitor);
+}
+
+void PFS_instance_iterator::visit_all_cond_classes(PFS_instance_visitor *visitor)
+{
+ PFS_cond_class *pfs= cond_class_array;
+ PFS_cond_class *pfs_last= pfs + cond_class_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_name_length != 0)
+ {
+ visitor->visit_cond_class(pfs);
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all_cond_instances(PFS_instance_visitor *visitor)
+{
+ PFS_cond *pfs= cond_array;
+ PFS_cond *pfs_last= pfs + cond_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ visitor->visit_cond(pfs);
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all_file(PFS_instance_visitor *visitor)
+{
+ visit_all_file_classes(visitor);
+ visit_all_file_instances(visitor);
+}
+
+void PFS_instance_iterator::visit_all_file_classes(PFS_instance_visitor *visitor)
+{
+ PFS_file_class *pfs= file_class_array;
+ PFS_file_class *pfs_last= pfs + file_class_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_name_length != 0)
+ {
+ visitor->visit_file_class(pfs);
+ }
+ }
+}
+
+void PFS_instance_iterator::visit_all_file_instances(PFS_instance_visitor *visitor)
+{
+ PFS_file *pfs= file_array;
+ PFS_file *pfs_last= pfs + file_max;
+ for ( ; pfs < pfs_last; pfs++)
+ {
+ if (pfs->m_lock.is_populated())
+ {
+ visitor->visit_file(pfs);
+ }
+ }
+}
+
void PFS_instance_iterator::visit_mutex_instances(PFS_mutex_class *klass,
PFS_instance_visitor *visitor)
{
@@ -175,6 +472,11 @@ void PFS_instance_iterator::visit_file_i
}
}
+void PFS_object_iterator::visit_all(PFS_object_visitor *visitor)
+{
+ visit_all_tables(visitor);
+}
+
void PFS_object_iterator::visit_all_tables(PFS_object_visitor *visitor)
{
DBUG_ASSERT(visitor != NULL);
@@ -258,11 +560,69 @@ void PFS_connection_wait_visitor::visit_
DBUG_ASSERT(false);
}
+void PFS_connection_wait_visitor::visit_host(PFS_host *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
+}
+
+void PFS_connection_wait_visitor::visit_user(PFS_user *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
+}
+
+void PFS_connection_wait_visitor::visit_account(PFS_account *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
+}
+
void PFS_connection_wait_visitor::visit_thread(PFS_thread *pfs)
{
m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
}
+PFS_connection_all_wait_visitor
+::PFS_connection_all_wait_visitor()
+{}
+
+PFS_connection_all_wait_visitor::~PFS_connection_all_wait_visitor()
+{}
+
+void PFS_connection_all_wait_visitor::visit_global()
+{
+ /* Sum by instances, not by connection */
+ DBUG_ASSERT(false);
+}
+
+void PFS_connection_all_wait_visitor::visit_connection_slice(PFS_connection_slice *pfs)
+{
+ PFS_single_stat *stat= pfs->m_instr_class_waits_stats;
+ PFS_single_stat *stat_last= stat + wait_class_max;
+ for ( ; stat < stat_last; stat++)
+ {
+ m_stat.aggregate(stat);
+ }
+}
+
+void PFS_connection_all_wait_visitor::visit_host(PFS_host *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
+void PFS_connection_all_wait_visitor::visit_user(PFS_user *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
+void PFS_connection_all_wait_visitor::visit_account(PFS_account *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
+void PFS_connection_all_wait_visitor::visit_thread(PFS_thread *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
PFS_connection_stage_visitor::PFS_connection_stage_visitor(PFS_stage_class *klass)
{
m_index= klass->m_event_name_index;
@@ -276,6 +636,21 @@ void PFS_connection_stage_visitor::visit
m_stat.aggregate(& global_instr_class_stages_array[m_index]);
}
+void PFS_connection_stage_visitor::visit_host(PFS_host *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
+}
+
+void PFS_connection_stage_visitor::visit_user(PFS_user *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
+}
+
+void PFS_connection_stage_visitor::visit_account(PFS_account *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
+}
+
void PFS_connection_stage_visitor::visit_thread(PFS_thread *pfs)
{
m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
@@ -295,11 +670,102 @@ void PFS_connection_statement_visitor::v
m_stat.aggregate(& global_instr_class_statements_array[m_index]);
}
+void PFS_connection_statement_visitor::visit_host(PFS_host *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
+}
+
+void PFS_connection_statement_visitor::visit_user(PFS_user *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
+}
+
+void PFS_connection_statement_visitor::visit_account(PFS_account *pfs)
+{
+ m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
+}
+
void PFS_connection_statement_visitor::visit_thread(PFS_thread *pfs)
{
m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
}
+PFS_connection_all_statement_visitor
+::PFS_connection_all_statement_visitor()
+{}
+
+PFS_connection_all_statement_visitor::~PFS_connection_all_statement_visitor()
+{}
+
+void PFS_connection_all_statement_visitor::visit_global()
+{
+ PFS_statement_stat *stat= global_instr_class_statements_array;
+ PFS_statement_stat *stat_last= stat + statement_class_max;
+ for ( ; stat < stat_last; stat++)
+ {
+ m_stat.aggregate(stat);
+ }
+}
+
+void PFS_connection_all_statement_visitor::visit_connection_slice(PFS_connection_slice *pfs)
+{
+ PFS_statement_stat *stat= pfs->m_instr_class_statements_stats;
+ PFS_statement_stat *stat_last= stat + statement_class_max;
+ for ( ; stat < stat_last; stat++)
+ {
+ m_stat.aggregate(stat);
+ }
+}
+
+void PFS_connection_all_statement_visitor::visit_host(PFS_host *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
+void PFS_connection_all_statement_visitor::visit_user(PFS_user *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
+void PFS_connection_all_statement_visitor::visit_account(PFS_account *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
+void PFS_connection_all_statement_visitor::visit_thread(PFS_thread *pfs)
+{
+ visit_connection_slice(pfs);
+}
+
+PFS_connection_stat_visitor::PFS_connection_stat_visitor()
+{}
+
+PFS_connection_stat_visitor::~PFS_connection_stat_visitor()
+{}
+
+void PFS_connection_stat_visitor::visit_global()
+{}
+
+void PFS_connection_stat_visitor::visit_host(PFS_host *pfs)
+{
+ m_stat.aggregate_disconnected(pfs->m_disconnected_count);
+}
+
+void PFS_connection_stat_visitor::visit_user(PFS_user *pfs)
+{
+ m_stat.aggregate_disconnected(pfs->m_disconnected_count);
+}
+
+void PFS_connection_stat_visitor::visit_account(PFS_account *pfs)
+{
+ m_stat.aggregate_disconnected(pfs->m_disconnected_count);
+}
+
+void PFS_connection_stat_visitor::visit_thread(PFS_thread *)
+{
+ m_stat.aggregate_active(1);
+}
+
PFS_instance_wait_visitor::PFS_instance_wait_visitor()
{
}
@@ -351,6 +817,33 @@ void PFS_instance_wait_visitor::visit_fi
m_stat.aggregate(& pfs->m_wait_stat);
}
+PFS_object_wait_visitor::PFS_object_wait_visitor()
+{}
+
+PFS_object_wait_visitor::~PFS_object_wait_visitor()
+{}
+
+void PFS_object_wait_visitor::visit_global()
+{
+ uint index;
+
+ index= global_table_io_class.m_event_name_index;
+ m_stat.aggregate(& global_instr_class_waits_array[index]);
+
+ index= global_table_lock_class.m_event_name_index;
+ m_stat.aggregate(& global_instr_class_waits_array[index]);
+}
+
+void PFS_object_wait_visitor::visit_table_share(PFS_table_share *pfs)
+{
+ pfs->m_table_stat.sum(& m_stat);
+}
+
+void PFS_object_wait_visitor::visit_table(PFS_table *pfs)
+{
+ pfs->m_table_stat.sum(& m_stat);
+}
+
PFS_table_io_wait_visitor::PFS_table_io_wait_visitor()
{}
=== modified file 'storage/perfschema/pfs_visitor.h'
--- a/storage/perfschema/pfs_visitor.h 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/pfs_visitor.h 2011-05-07 00:40:25 +0000
@@ -28,6 +28,9 @@
@{
*/
+struct PFS_user;
+struct PFS_account;
+struct PFS_host;
struct PFS_thread;
struct PFS_instr_class;
struct PFS_mutex_class;
@@ -42,6 +45,7 @@ struct PFS_file;
struct PFS_table;
struct PFS_stage_class;
struct PFS_statement_class;
+struct PFS_connection_slice;
/**
Interface class to visit groups of connections.
@@ -54,6 +58,12 @@ public:
virtual ~PFS_connection_visitor() {}
/** Visit all connections. */
virtual void visit_global() {}
+ /** Visit all connections of a host. */
+ virtual void visit_host(PFS_host *pfs) {}
+ /** Visit all connections of a user+host. */
+ virtual void visit_account(PFS_account *pfs) {}
+ /** Visit all connections of a user. */
+ virtual void visit_user(PFS_user *pfs) {}
/** Visit all a thread. */
virtual void visit_thread(PFS_thread *pfs) {}
};
@@ -67,12 +77,42 @@ class PFS_connection_iterator
public:
/**
Visit all connections.
+ @param with_hosts when true, visit also all hosts.
+ @param with_users when true, visit also all users.
+ @param with_accounts when true, visit also all user+host.
@param with_threads when true, visit also all threads.
@param visitor the visitor to call
*/
- static void visit_global(bool with_threads,
+ static void visit_global(bool with_hosts, bool with_users,
+ bool with_accounts, bool with_threads,
PFS_connection_visitor *visitor);
/**
+ Visit all connections of a host.
+ @param host the host to visit.
+ @param with_accounts when true, visit also all related user+host.
+ @param with_threads when true, visit also all related threads.
+ @param visitor the visitor to call
+ */
+ static void visit_host(PFS_host *host, bool with_accounts, bool with_threads,
+ PFS_connection_visitor *visitor);
+ /**
+ Visit all connections of a user.
+ @param user the user to visit.
+ @param with_accounts when true, visit also all related user+host.
+ @param with_threads when true, visit also all related threads.
+ @param visitor the visitor to call
+ */
+ static void visit_user(PFS_user *user, bool with_accounts, bool with_threads,
+ PFS_connection_visitor *visitor);
+ /**
+ Visit all connections of a user+host.
+ @param account the user+host to visit.
+ @param with_threads when true, visit also all related threads.
+ @param visitor the visitor to call
+ */
+ static void visit_account(PFS_account *account, bool with_threads,
+ PFS_connection_visitor *visitor);
+ /**
Visit a thread or connection.
@param thread the thread to visit.
@param visitor the visitor to call
@@ -116,6 +156,20 @@ public:
class PFS_instance_iterator
{
public:
+ static void visit_all(PFS_instance_visitor *visitor);
+ static void visit_all_mutex(PFS_instance_visitor *visitor);
+ static void visit_all_mutex_classes(PFS_instance_visitor *visitor);
+ static void visit_all_mutex_instances(PFS_instance_visitor *visitor);
+ static void visit_all_rwlock(PFS_instance_visitor *visitor);
+ static void visit_all_rwlock_classes(PFS_instance_visitor *visitor);
+ static void visit_all_rwlock_instances(PFS_instance_visitor *visitor);
+ static void visit_all_cond(PFS_instance_visitor *visitor);
+ static void visit_all_cond_classes(PFS_instance_visitor *visitor);
+ static void visit_all_cond_instances(PFS_instance_visitor *visitor);
+ static void visit_all_file(PFS_instance_visitor *visitor);
+ static void visit_all_file_classes(PFS_instance_visitor *visitor);
+ static void visit_all_file_instances(PFS_instance_visitor *visitor);
+
/**
Visit a mutex class and related instances.
@param klass the klass to visit.
@@ -174,6 +228,8 @@ public:
class PFS_object_iterator
{
public:
+ /** Visit all objects. */
+ static void visit_all(PFS_object_visitor *visitor);
/** Visit all tables and related handles. */
static void visit_all_tables(PFS_object_visitor *visitor);
/** Visit a table and related table handles. */
@@ -187,7 +243,7 @@ public:
/**
A concrete connection visitor that aggregates
- wait statistics.
+ wait statistics for a given event_name.
*/
class PFS_connection_wait_visitor : public PFS_connection_visitor
{
@@ -196,6 +252,9 @@ public:
PFS_connection_wait_visitor(PFS_instr_class *klass);
virtual ~PFS_connection_wait_visitor();
virtual void visit_global();
+ virtual void visit_host(PFS_host *pfs);
+ virtual void visit_account(PFS_account *pfs);
+ virtual void visit_user(PFS_user *pfs);
virtual void visit_thread(PFS_thread *pfs);
/** EVENT_NAME instrument index. */
@@ -206,6 +265,29 @@ public:
/**
A concrete connection visitor that aggregates
+ wait statistics for all events.
+*/
+class PFS_connection_all_wait_visitor : public PFS_connection_visitor
+{
+public:
+ /** Constructor. */
+ PFS_connection_all_wait_visitor();
+ virtual ~PFS_connection_all_wait_visitor();
+ virtual void visit_global();
+ virtual void visit_host(PFS_host *pfs);
+ virtual void visit_account(PFS_account *pfs);
+ virtual void visit_user(PFS_user *pfs);
+ virtual void visit_thread(PFS_thread *pfs);
+
+ /** Wait statistic collected. */
+ PFS_single_stat m_stat;
+
+private:
+ void visit_connection_slice(PFS_connection_slice *pfs);
+};
+
+/**
+ A concrete connection visitor that aggregates
stage statistics.
*/
class PFS_connection_stage_visitor : public PFS_connection_visitor
@@ -215,6 +297,9 @@ public:
PFS_connection_stage_visitor(PFS_stage_class *klass);
virtual ~PFS_connection_stage_visitor();
virtual void visit_global();
+ virtual void visit_host(PFS_host *pfs);
+ virtual void visit_account(PFS_account *pfs);
+ virtual void visit_user(PFS_user *pfs);
virtual void visit_thread(PFS_thread *pfs);
/** EVENT_NAME instrument index. */
@@ -225,7 +310,7 @@ public:
/**
A concrete connection visitor that aggregates
- statement statistics.
+ statement statistics for a given event_name.
*/
class PFS_connection_statement_visitor : public PFS_connection_visitor
{
@@ -234,6 +319,9 @@ public:
PFS_connection_statement_visitor(PFS_statement_class *klass);
virtual ~PFS_connection_statement_visitor();
virtual void visit_global();
+ virtual void visit_host(PFS_host *pfs);
+ virtual void visit_account(PFS_account *pfs);
+ virtual void visit_user(PFS_user *pfs);
virtual void visit_thread(PFS_thread *pfs);
/** EVENT_NAME instrument index. */
@@ -243,6 +331,49 @@ public:
};
/**
+ A concrete connection visitor that aggregates
+ statement statistics for all events.
+*/
+class PFS_connection_all_statement_visitor : public PFS_connection_visitor
+{
+public:
+ /** Constructor. */
+ PFS_connection_all_statement_visitor();
+ virtual ~PFS_connection_all_statement_visitor();
+ virtual void visit_global();
+ virtual void visit_host(PFS_host *pfs);
+ virtual void visit_account(PFS_account *pfs);
+ virtual void visit_user(PFS_user *pfs);
+ virtual void visit_thread(PFS_thread *pfs);
+
+ /** Statement statistic collected. */
+ PFS_statement_stat m_stat;
+
+private:
+ void visit_connection_slice(PFS_connection_slice *pfs);
+};
+
+/**
+ A concrete connection visitor that aggregates
+ connection statistics.
+*/
+class PFS_connection_stat_visitor : public PFS_connection_visitor
+{
+public:
+ /** Constructor. */
+ PFS_connection_stat_visitor();
+ virtual ~PFS_connection_stat_visitor();
+ virtual void visit_global();
+ virtual void visit_host(PFS_host *pfs);
+ virtual void visit_account(PFS_account *pfs);
+ virtual void visit_user(PFS_user *pfs);
+ virtual void visit_thread(PFS_thread *pfs);
+
+ /** Connection statistic collected. */
+ PFS_connection_stat m_stat;
+};
+
+/**
A concrete instance visitor that aggregates
wait statistics.
*/
@@ -266,6 +397,23 @@ public:
/**
A concrete object visitor that aggregates
+ object wait statistics.
+*/
+class PFS_object_wait_visitor : public PFS_object_visitor
+{
+public:
+ PFS_object_wait_visitor();
+ virtual ~PFS_object_wait_visitor();
+ virtual void visit_global();
+ virtual void visit_table_share(PFS_table_share *pfs);
+ virtual void visit_table(PFS_table *pfs);
+
+ /** Object wait statistic collected. */
+ PFS_single_stat m_stat;
+};
+
+/**
+ A concrete object visitor that aggregates
table io wait statistics.
*/
class PFS_table_io_wait_visitor : public PFS_object_visitor
=== added file 'storage/perfschema/table_accounts.cc'
--- a/storage/perfschema/table_accounts.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_accounts.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,148 @@
+/* Copyright (c) 2011, 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "table_accounts.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_account.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_accounts::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("CURRENT_CONNECTIONS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("TOTAL_CONNECTIONS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_accounts::m_field_def=
+{ 4, field_types };
+
+PFS_engine_table_share
+table_accounts::m_share=
+{
+ { C_STRING_WITH_LEN("accounts") },
+ &pfs_truncatable_acl,
+ &table_accounts::create,
+ NULL, /* write_row */
+ table_accounts::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(PFS_simple_index), /* ref length */
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table* table_accounts::create()
+{
+ return new table_accounts();
+}
+
+int
+table_accounts::delete_all_rows(void)
+{
+ reset_events_waits_by_thread();
+ reset_events_waits_by_account();
+ reset_events_stages_by_thread();
+ reset_events_stages_by_account();
+ reset_events_statements_by_thread();
+ reset_events_statements_by_account();
+ purge_all_account();
+ return 0;
+}
+
+table_accounts::table_accounts()
+ : cursor_by_account(& m_share),
+ m_row_exists(false)
+{}
+
+void table_accounts::make_row(PFS_account *pfs)
+{
+ pfs_lock lock;
+
+ m_row_exists= false;
+ pfs->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_account.make_row(pfs))
+ return;
+
+ PFS_connection_stat_visitor visitor;
+ PFS_connection_iterator::visit_account(pfs, true, & visitor);
+
+ if (! pfs->m_lock.end_optimistic_lock(& lock))
+ return;
+
+ m_row.m_connection_stat.set(& visitor.m_stat);
+ m_row_exists= true;
+}
+
+int table_accounts::read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ case 1: /* HOST */
+ m_row.m_account.set_field(f->field_index, f);
+ break;
+ case 2: /* CURRENT_CONNECTIONS */
+ case 3: /* TOTAL_CONNECTIONS */
+ m_row.m_connection_stat.set_field(f->field_index - 2, f);
+ break;
+ default:
+ DBUG_ASSERT(false);
+ }
+ }
+ }
+ return 0;
+}
+
=== added file 'storage/perfschema/table_accounts.h'
--- a/storage/perfschema/table_accounts.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_accounts.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,80 @@
+/* Copyright (c) 2011, 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef TABLE_ACCOUNTS_H
+#define TABLE_ACCOUNTS_H
+
+#include "pfs_column_types.h"
+#include "cursor_by_account.h"
+#include "table_helper.h"
+
+struct PFS_account;
+
+/**
+ \addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of PERFORMANCE_SCHEMA.ACCOUNTS.
+*/
+struct row_accounts
+{
+ /** Column USER, HOST. */
+ PFS_account_row m_account;
+ /** Columns CURRENT_CONNECTIONS, TOTAL_CONNECTIONS. */
+ PFS_connection_stat_row m_connection_stat;
+};
+
+/** Table PERFORMANCE_SCHEMA.ACCOUNTS. */
+class table_accounts : public cursor_by_account
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ /** Table builder */
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+
+protected:
+ table_accounts();
+
+public:
+ ~table_accounts()
+ {}
+
+private:
+ virtual void make_row(PFS_account *pfs);
+
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_accounts m_row;
+ /** True if the current row exists. */
+ bool m_row_exists;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/table_esgs_by_account_by_event_name.cc'
--- a/storage/perfschema/table_esgs_by_account_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esgs_by_account_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,229 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_esgs_by_account_by_event_name.cc
+ Table EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_esgs_by_account_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_esgs_by_account_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_esgs_by_account_by_event_name::m_field_def=
+{ 8, field_types };
+
+PFS_engine_table_share
+table_esgs_by_account_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_stages_summary_by_account_by_event_name") },
+ &pfs_truncatable_acl,
+ table_esgs_by_account_by_event_name::create,
+ NULL, /* write_row */
+ table_esgs_by_account_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_esgs_by_account_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_esgs_by_account_by_event_name::create(void)
+{
+ return new table_esgs_by_account_by_event_name();
+}
+
+int
+table_esgs_by_account_by_event_name::delete_all_rows(void)
+{
+ reset_events_stages_by_thread();
+ reset_events_stages_by_account();
+ return 0;
+}
+
+table_esgs_by_account_by_event_name::table_esgs_by_account_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_esgs_by_account_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_esgs_by_account_by_event_name::rnd_next(void)
+{
+ PFS_account *account;
+ PFS_stage_class *stage_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_account();
+ m_pos.next_account())
+ {
+ account= &account_array[m_pos.m_index_1];
+ if (account->m_lock.is_populated())
+ {
+ stage_class= find_stage_class(m_pos.m_index_2);
+ if (stage_class)
+ {
+ make_row(account, stage_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_esgs_by_account_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_account *account;
+ PFS_stage_class *stage_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < account_max);
+
+ account= &account_array[m_pos.m_index_1];
+ if (! account->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ stage_class= find_stage_class(m_pos.m_index_2);
+ if (stage_class)
+ {
+ make_row(account, stage_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_esgs_by_account_by_event_name
+::make_row(PFS_account *account, PFS_stage_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ account->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_account.make_row(account))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_stage_visitor visitor(klass);
+ PFS_connection_iterator::visit_account(account, true, & visitor);
+
+ if (! account->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(stage_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_esgs_by_account_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ case 1: /* HOST */
+ m_row.m_account.set_field(f->field_index, f);
+ break;
+ case 2: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 3, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 3, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_esgs_by_account_by_event_name.h'
--- a/storage/perfschema/table_esgs_by_account_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esgs_by_account_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,124 @@
+/* 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 */
+
+#ifndef TABLE_ESGS_BY_ACCOUNT_BY_EVENT_NAME_H
+#define TABLE_ESGS_BY_ACCOUNT_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_esgs_by_account_by_event_name.h
+ Table EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_account.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME.
+*/
+struct row_esgs_by_account_by_event_name
+{
+ /** Column USER, HOST. */
+ PFS_account_row m_account;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_stage_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME.
+ Index 1 on user@host (0 based)
+ Index 2 on stage class (1 based)
+*/
+struct pos_esgs_by_account_by_event_name
+: public PFS_double_index
+{
+ pos_esgs_by_account_by_event_name()
+ : PFS_double_index(0, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= 1;
+ }
+
+ inline bool has_more_account(void)
+ { return (m_index_1 < account_max); }
+
+ inline void next_account(void)
+ {
+ m_index_1++;
+ m_index_2= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME. */
+class table_esgs_by_account_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_esgs_by_account_by_event_name();
+
+public:
+ ~table_esgs_by_account_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_account *account, PFS_stage_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_esgs_by_account_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_esgs_by_account_by_event_name m_pos;
+ /** Next position. */
+ pos_esgs_by_account_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/table_esgs_by_host_by_event_name.cc'
--- a/storage/perfschema/table_esgs_by_host_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esgs_by_host_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,225 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_esgs_by_host_by_event_name.cc
+ Table EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_esgs_by_host_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_account.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_esgs_by_host_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_esgs_by_host_by_event_name::m_field_def=
+{ 7, field_types };
+
+PFS_engine_table_share
+table_esgs_by_host_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_stages_summary_by_host_by_event_name") },
+ &pfs_truncatable_acl,
+ table_esgs_by_host_by_event_name::create,
+ NULL, /* write_row */
+ table_esgs_by_host_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_esgs_by_host_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_esgs_by_host_by_event_name::create(void)
+{
+ return new table_esgs_by_host_by_event_name();
+}
+
+int
+table_esgs_by_host_by_event_name::delete_all_rows(void)
+{
+ reset_events_stages_by_thread();
+ reset_events_stages_by_account();
+ reset_events_stages_by_host();
+ return 0;
+}
+
+table_esgs_by_host_by_event_name::table_esgs_by_host_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_esgs_by_host_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_esgs_by_host_by_event_name::rnd_next(void)
+{
+ PFS_host *host;
+ PFS_stage_class *stage_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_host();
+ m_pos.next_host())
+ {
+ host= &host_array[m_pos.m_index_1];
+ if (host->m_lock.is_populated())
+ {
+ stage_class= find_stage_class(m_pos.m_index_2);
+ if (stage_class)
+ {
+ make_row(host, stage_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_esgs_by_host_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_host *host;
+ PFS_stage_class *stage_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < host_max);
+
+ host= &host_array[m_pos.m_index_1];
+ if (! host->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ stage_class= find_stage_class(m_pos.m_index_2);
+ if (stage_class)
+ {
+ make_row(host, stage_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_esgs_by_host_by_event_name
+::make_row(PFS_host *host, PFS_stage_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ host->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_host.make_row(host))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_stage_visitor visitor(klass);
+ PFS_connection_iterator::visit_host(host, true, true, & visitor);
+
+ if (! host->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(stage_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_esgs_by_host_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* HOST */
+ m_row.m_host.set_field(f);
+ break;
+ case 1: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 2, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_esgs_by_host_by_event_name.h'
--- a/storage/perfschema/table_esgs_by_host_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esgs_by_host_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,124 @@
+/* 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 */
+
+#ifndef TABLE_ESGS_BY_HOST_BY_EVENT_NAME_H
+#define TABLE_ESGS_BY_HOST_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_esgs_by_host_by_event_name.h
+ Table EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_host.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME.
+*/
+struct row_esgs_by_host_by_event_name
+{
+ /** Column HOST. */
+ PFS_host_row m_host;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_stage_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME.
+ Index 1 on host (0 based)
+ Index 2 on stage class (1 based).
+*/
+struct pos_esgs_by_host_by_event_name
+: public PFS_double_index
+{
+ pos_esgs_by_host_by_event_name()
+ : PFS_double_index(0, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= 1;
+ }
+
+ inline bool has_more_host(void)
+ { return (m_index_1 < host_max); }
+
+ inline void next_host(void)
+ {
+ m_index_1++;
+ m_index_2= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME. */
+class table_esgs_by_host_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_esgs_by_host_by_event_name();
+
+public:
+ ~table_esgs_by_host_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_host *host, PFS_stage_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_esgs_by_host_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_esgs_by_host_by_event_name m_pos;
+ /** Next position. */
+ pos_esgs_by_host_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/table_esgs_by_user_by_event_name.cc'
--- a/storage/perfschema/table_esgs_by_user_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esgs_by_user_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,225 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_esgs_by_user_by_event_name.cc
+ Table EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_esgs_by_user_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_account.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_esgs_by_user_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_esgs_by_user_by_event_name::m_field_def=
+{ 7, field_types };
+
+PFS_engine_table_share
+table_esgs_by_user_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_stages_summary_by_user_by_event_name") },
+ &pfs_truncatable_acl,
+ table_esgs_by_user_by_event_name::create,
+ NULL, /* write_row */
+ table_esgs_by_user_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_esgs_by_user_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_esgs_by_user_by_event_name::create(void)
+{
+ return new table_esgs_by_user_by_event_name();
+}
+
+int
+table_esgs_by_user_by_event_name::delete_all_rows(void)
+{
+ reset_events_stages_by_thread();
+ reset_events_stages_by_account();
+ reset_events_stages_by_user();
+ return 0;
+}
+
+table_esgs_by_user_by_event_name::table_esgs_by_user_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_esgs_by_user_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_esgs_by_user_by_event_name::rnd_next(void)
+{
+ PFS_user *user;
+ PFS_stage_class *stage_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_user();
+ m_pos.next_user())
+ {
+ user= &user_array[m_pos.m_index_1];
+ if (user->m_lock.is_populated())
+ {
+ stage_class= find_stage_class(m_pos.m_index_2);
+ if (stage_class)
+ {
+ make_row(user, stage_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_esgs_by_user_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_user *user;
+ PFS_stage_class *stage_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < user_max);
+
+ user= &user_array[m_pos.m_index_1];
+ if (! user->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ stage_class= find_stage_class(m_pos.m_index_2);
+ if (stage_class)
+ {
+ make_row(user, stage_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_esgs_by_user_by_event_name
+::make_row(PFS_user *user, PFS_stage_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ user->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_user.make_row(user))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_stage_visitor visitor(klass);
+ PFS_connection_iterator::visit_user(user, true, true, & visitor);
+
+ if (! user->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(stage_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_esgs_by_user_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ m_row.m_user.set_field(f);
+ break;
+ case 1: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 2, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_esgs_by_user_by_event_name.h'
--- a/storage/perfschema/table_esgs_by_user_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esgs_by_user_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,129 @@
+/* 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 */
+
+#ifndef TABLE_ESGS_BY_USER_BY_EVENT_NAME_H
+#define TABLE_ESGS_BY_USER_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_esgs_by_user_by_event_name.h
+ Table EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_user.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME.
+*/
+struct row_esgs_by_user_by_event_name
+{
+ /** Column USER. */
+ PFS_user_row m_user;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_stage_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME.
+ Index 1 on user (0 based)
+ Index 2 on stage class (1 based)
+*/
+struct pos_esgs_by_user_by_event_name
+: public PFS_double_index
+{
+ pos_esgs_by_user_by_event_name()
+ : PFS_double_index(0, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= 1;
+ }
+
+ inline bool has_more_user(void)
+ { return (m_index_1 < user_max); }
+
+ inline void next_user(void)
+ {
+ m_index_1++;
+ m_index_2= 1;
+ }
+
+ inline void next_stage(void)
+ {
+ m_index_2++;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME. */
+class table_esgs_by_user_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_esgs_by_user_by_event_name();
+
+public:
+ ~table_esgs_by_user_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_user *user, PFS_stage_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_esgs_by_user_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_esgs_by_user_by_event_name m_pos;
+ /** Next position. */
+ pos_esgs_by_user_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== modified file 'storage/perfschema/table_esgs_global_by_event_name.cc'
--- a/storage/perfschema/table_esgs_global_by_event_name.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/table_esgs_global_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -157,7 +157,9 @@ void table_esgs_global_by_event_name
m_row.m_event_name.make_row(klass);
PFS_connection_stage_visitor visitor(klass);
- PFS_connection_iterator::visit_global(true, & visitor);
+ PFS_connection_iterator::visit_global(true, /* hosts */
+ false, /* users */
+ true, true, & visitor);
time_normalizer *normalizer= time_normalizer::get(stage_timer);
m_row.m_stat.set(normalizer, & visitor.m_stat);
=== added file 'storage/perfschema/table_esms_by_account_by_event_name.cc'
--- a/storage/perfschema/table_esms_by_account_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esms_by_account_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,324 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_esms_by_account_by_event_name.cc
+ Table EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_esms_by_account_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_esms_by_account_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_LOCK_TIME") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ERRORS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_WARNINGS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_AFFECTED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_SENT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_EXAMINED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_CREATED_TMP_DISK_TABLES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_CREATED_TMP_TABLES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_FULL_JOIN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_FULL_RANGE_JOIN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_RANGE") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_RANGE_CHECK") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_SCAN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_MERGE_PASSES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_RANGE") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_ROWS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_SCAN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_NO_INDEX_USED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_NO_GOOD_INDEX_USED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_esms_by_account_by_event_name::m_field_def=
+{ 27, field_types };
+
+PFS_engine_table_share
+table_esms_by_account_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_statements_summary_by_account_by_event_name") },
+ &pfs_truncatable_acl,
+ table_esms_by_account_by_event_name::create,
+ NULL, /* write_row */
+ table_esms_by_account_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_esms_by_account_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_esms_by_account_by_event_name::create(void)
+{
+ return new table_esms_by_account_by_event_name();
+}
+
+int
+table_esms_by_account_by_event_name::delete_all_rows(void)
+{
+ reset_events_statements_by_thread();
+ reset_events_statements_by_account();
+ return 0;
+}
+
+table_esms_by_account_by_event_name::table_esms_by_account_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_esms_by_account_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_esms_by_account_by_event_name::rnd_next(void)
+{
+ PFS_account *account;
+ PFS_statement_class *statement_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_account();
+ m_pos.next_account())
+ {
+ account= &account_array[m_pos.m_index_1];
+ if (account->m_lock.is_populated())
+ {
+ statement_class= find_statement_class(m_pos.m_index_2);
+ if (statement_class)
+ {
+ make_row(account, statement_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_esms_by_account_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_account *account;
+ PFS_statement_class *statement_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < account_max);
+
+ account= &account_array[m_pos.m_index_1];
+ if (! account->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ statement_class= find_statement_class(m_pos.m_index_2);
+ if (statement_class)
+ {
+ make_row(account, statement_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_esms_by_account_by_event_name
+::make_row(PFS_account *account, PFS_statement_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ account->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_account.make_row(account))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_statement_visitor visitor(klass);
+ PFS_connection_iterator::visit_account(account, true, & visitor);
+
+ if (! account->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(statement_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_esms_by_account_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ case 1: /* HOST */
+ m_row.m_account.set_field(f->field_index, f);
+ break;
+ case 2: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 3, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 3, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_esms_by_account_by_event_name.h'
--- a/storage/perfschema/table_esms_by_account_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esms_by_account_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,124 @@
+/* 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 */
+
+#ifndef TABLE_ESMS_BY_ACCOUNT_BY_EVENT_NAME_H
+#define TABLE_ESMS_BY_ACCOUNT_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_esms_by_account_by_event_name.h
+ Table EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_account.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME.
+*/
+struct row_esms_by_account_by_event_name
+{
+ /** Column USER, HOST. */
+ PFS_account_row m_account;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_statement_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME.
+ Index 1 on user@host (0 based)
+ Index 2 on statement class (1 based)
+*/
+struct pos_esms_by_account_by_event_name
+: public PFS_double_index
+{
+ pos_esms_by_account_by_event_name()
+ : PFS_double_index(0, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= 1;
+ }
+
+ inline bool has_more_account(void)
+ { return (m_index_1 < account_max); }
+
+ inline void next_account(void)
+ {
+ m_index_1++;
+ m_index_2= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME. */
+class table_esms_by_account_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_esms_by_account_by_event_name();
+
+public:
+ ~table_esms_by_account_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_account *account, PFS_statement_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_esms_by_account_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_esms_by_account_by_event_name m_pos;
+ /** Next position. */
+ pos_esms_by_account_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/table_esms_by_host_by_event_name.cc'
--- a/storage/perfschema/table_esms_by_host_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esms_by_host_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,320 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_esms_by_host_by_event_name.cc
+ Table EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_esms_by_host_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_account.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_esms_by_host_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_LOCK_TIME") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ERRORS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_WARNINGS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_AFFECTED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_SENT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_EXAMINED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_CREATED_TMP_DISK_TABLES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_CREATED_TMP_TABLES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_FULL_JOIN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_FULL_RANGE_JOIN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_RANGE") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_RANGE_CHECK") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_SCAN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_MERGE_PASSES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_RANGE") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_ROWS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_SCAN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_NO_INDEX_USED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_NO_GOOD_INDEX_USED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_esms_by_host_by_event_name::m_field_def=
+{ 26, field_types };
+
+PFS_engine_table_share
+table_esms_by_host_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_statements_summary_by_host_by_event_name") },
+ &pfs_truncatable_acl,
+ table_esms_by_host_by_event_name::create,
+ NULL, /* write_row */
+ table_esms_by_host_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_esms_by_host_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_esms_by_host_by_event_name::create(void)
+{
+ return new table_esms_by_host_by_event_name();
+}
+
+int
+table_esms_by_host_by_event_name::delete_all_rows(void)
+{
+ reset_events_statements_by_thread();
+ reset_events_statements_by_account();
+ reset_events_statements_by_host();
+ return 0;
+}
+
+table_esms_by_host_by_event_name::table_esms_by_host_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_esms_by_host_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_esms_by_host_by_event_name::rnd_next(void)
+{
+ PFS_host *host;
+ PFS_statement_class *statement_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_host();
+ m_pos.next_host())
+ {
+ host= &host_array[m_pos.m_index_1];
+ if (host->m_lock.is_populated())
+ {
+ statement_class= find_statement_class(m_pos.m_index_2);
+ if (statement_class)
+ {
+ make_row(host, statement_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_esms_by_host_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_host *host;
+ PFS_statement_class *statement_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < host_max);
+
+ host= &host_array[m_pos.m_index_1];
+ if (! host->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ statement_class= find_statement_class(m_pos.m_index_2);
+ if (statement_class)
+ {
+ make_row(host, statement_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_esms_by_host_by_event_name
+::make_row(PFS_host *host, PFS_statement_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ host->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_host.make_row(host))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_statement_visitor visitor(klass);
+ PFS_connection_iterator::visit_host(host, true, true, & visitor);
+
+ if (! host->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(statement_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_esms_by_host_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* HOST */
+ m_row.m_host.set_field(f);
+ break;
+ case 1: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 2, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_esms_by_host_by_event_name.h'
--- a/storage/perfschema/table_esms_by_host_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esms_by_host_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,124 @@
+/* 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 */
+
+#ifndef TABLE_ESMS_BY_HOST_BY_EVENT_NAME_H
+#define TABLE_ESMS_BY_HOST_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_esms_by_host_by_event_name.h
+ Table EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_host.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME.
+*/
+struct row_esms_by_host_by_event_name
+{
+ /** Column HOST */
+ PFS_host_row m_host;
+ /** Column EVENT_NAME */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_statement_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME.
+ Index 1 on host (0 based)
+ Index 2 on statement class (1 based)
+*/
+struct pos_esms_by_host_by_event_name
+: public PFS_double_index
+{
+ pos_esms_by_host_by_event_name()
+ : PFS_double_index(0, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= 1;
+ }
+
+ inline bool has_more_host(void)
+ { return (m_index_1 < host_max); }
+
+ inline void next_host(void)
+ {
+ m_index_1++;
+ m_index_2= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME. */
+class table_esms_by_host_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_esms_by_host_by_event_name();
+
+public:
+ ~table_esms_by_host_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_host *host, PFS_statement_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_esms_by_host_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_esms_by_host_by_event_name m_pos;
+ /** Next position. */
+ pos_esms_by_host_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/table_esms_by_user_by_event_name.cc'
--- a/storage/perfschema/table_esms_by_user_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esms_by_user_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,320 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_esms_by_user_by_event_name.cc
+ Table EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_esms_by_user_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_account.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_esms_by_user_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_LOCK_TIME") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ERRORS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_WARNINGS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_AFFECTED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_SENT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_ROWS_EXAMINED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_CREATED_TMP_DISK_TABLES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_CREATED_TMP_TABLES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_FULL_JOIN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_FULL_RANGE_JOIN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_RANGE") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_RANGE_CHECK") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SELECT_SCAN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_MERGE_PASSES") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_RANGE") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_ROWS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_SORT_SCAN") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_NO_INDEX_USED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_NO_GOOD_INDEX_USED") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_esms_by_user_by_event_name::m_field_def=
+{ 26, field_types };
+
+PFS_engine_table_share
+table_esms_by_user_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_statements_summary_by_user_by_event_name") },
+ &pfs_truncatable_acl,
+ table_esms_by_user_by_event_name::create,
+ NULL, /* write_row */
+ table_esms_by_user_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_esms_by_user_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_esms_by_user_by_event_name::create(void)
+{
+ return new table_esms_by_user_by_event_name();
+}
+
+int
+table_esms_by_user_by_event_name::delete_all_rows(void)
+{
+ reset_events_statements_by_thread();
+ reset_events_statements_by_account();
+ reset_events_statements_by_user();
+ return 0;
+}
+
+table_esms_by_user_by_event_name::table_esms_by_user_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_esms_by_user_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_esms_by_user_by_event_name::rnd_next(void)
+{
+ PFS_user *user;
+ PFS_statement_class *statement_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_user();
+ m_pos.next_user())
+ {
+ user= &user_array[m_pos.m_index_1];
+ if (user->m_lock.is_populated())
+ {
+ statement_class= find_statement_class(m_pos.m_index_2);
+ if (statement_class)
+ {
+ make_row(user, statement_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_esms_by_user_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_user *user;
+ PFS_statement_class *statement_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < user_max);
+
+ user= &user_array[m_pos.m_index_1];
+ if (! user->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ statement_class= find_statement_class(m_pos.m_index_2);
+ if (statement_class)
+ {
+ make_row(user, statement_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_esms_by_user_by_event_name
+::make_row(PFS_user *user, PFS_statement_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ user->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_user.make_row(user))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_statement_visitor visitor(klass);
+ PFS_connection_iterator::visit_user(user, true, true, & visitor);
+
+ if (! user->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(statement_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_esms_by_user_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ m_row.m_user.set_field(f);
+ break;
+ case 1: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 2, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_esms_by_user_by_event_name.h'
--- a/storage/perfschema/table_esms_by_user_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_esms_by_user_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,124 @@
+/* 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 */
+
+#ifndef TABLE_ESMS_BY_USER_BY_EVENT_NAME_H
+#define TABLE_ESMS_BY_USER_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_esms_by_user_by_event_name.h
+ Table EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_user.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME.
+*/
+struct row_esms_by_user_by_event_name
+{
+ /** Column USER. */
+ PFS_user_row m_user;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_statement_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME.
+ Index 1 on user (0 based)
+ Index 2 on statement class (1 based)
+*/
+struct pos_esms_by_user_by_event_name
+: public PFS_double_index
+{
+ pos_esms_by_user_by_event_name()
+ : PFS_double_index(0, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= 1;
+ }
+
+ inline bool has_more_user(void)
+ { return (m_index_1 < user_max); }
+
+ inline void next_user(void)
+ {
+ m_index_1++;
+ m_index_2= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME. */
+class table_esms_by_user_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_esms_by_user_by_event_name();
+
+public:
+ ~table_esms_by_user_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_user *user, PFS_statement_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_esms_by_user_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_esms_by_user_by_event_name m_pos;
+ /** Next position. */
+ pos_esms_by_user_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== modified file 'storage/perfschema/table_esms_global_by_event_name.cc'
--- a/storage/perfschema/table_esms_global_by_event_name.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/table_esms_global_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -252,7 +252,9 @@ void table_esms_global_by_event_name
m_row.m_event_name.make_row(klass);
PFS_connection_statement_visitor visitor(klass);
- PFS_connection_iterator::visit_global(true, & visitor);
+ PFS_connection_iterator::visit_global(true, /* hosts */
+ false, /* users */
+ true, true, & visitor);
time_normalizer *normalizer= time_normalizer::get(statement_timer);
m_row.m_stat.set(normalizer, & visitor.m_stat);
=== added file 'storage/perfschema/table_ews_by_account_by_event_name.cc'
--- a/storage/perfschema/table_ews_by_account_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_ews_by_account_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,276 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_ews_by_account_by_event_name.cc
+ Table EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_ews_by_account_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_ews_by_account_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_ews_by_account_by_event_name::m_field_def=
+{ 8, field_types };
+
+PFS_engine_table_share
+table_ews_by_account_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_waits_summary_by_account_by_event_name") },
+ &pfs_truncatable_acl,
+ table_ews_by_account_by_event_name::create,
+ NULL, /* write_row */
+ table_ews_by_account_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_ews_by_account_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_ews_by_account_by_event_name::create(void)
+{
+ return new table_ews_by_account_by_event_name();
+}
+
+int
+table_ews_by_account_by_event_name::delete_all_rows(void)
+{
+ reset_events_waits_by_thread();
+ reset_events_waits_by_account();
+ return 0;
+}
+
+table_ews_by_account_by_event_name::table_ews_by_account_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_ews_by_account_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_ews_by_account_by_event_name::rnd_next(void)
+{
+ PFS_account *account;
+ PFS_instr_class *instr_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_account();
+ m_pos.next_account())
+ {
+ account= &account_array[m_pos.m_index_1];
+ if (account->m_lock.is_populated())
+ {
+ for ( ;
+ m_pos.has_more_view();
+ m_pos.next_view())
+ {
+ switch (m_pos.m_index_2)
+ {
+ case pos_ews_by_account_by_event_name::VIEW_MUTEX:
+ instr_class= find_mutex_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_RWLOCK:
+ instr_class= find_rwlock_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_COND:
+ instr_class= find_cond_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_FILE:
+ instr_class= find_file_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_TABLE:
+ instr_class= find_table_class(m_pos.m_index_3);
+ break;
+ default:
+ instr_class= NULL;
+ DBUG_ASSERT(false);
+ break;
+ }
+
+ if (instr_class)
+ {
+ make_row(account, instr_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_ews_by_account_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_account *account;
+ PFS_instr_class *instr_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < account_max);
+
+ account= &account_array[m_pos.m_index_1];
+ if (! account->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ switch (m_pos.m_index_2)
+ {
+ case pos_ews_by_account_by_event_name::VIEW_MUTEX:
+ instr_class= find_mutex_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_RWLOCK:
+ instr_class= find_rwlock_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_COND:
+ instr_class= find_cond_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_FILE:
+ instr_class= find_file_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_account_by_event_name::VIEW_TABLE:
+ instr_class= find_table_class(m_pos.m_index_3);
+ break;
+ default:
+ instr_class= NULL;
+ DBUG_ASSERT(false);
+ }
+ if (instr_class)
+ {
+ make_row(account, instr_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_ews_by_account_by_event_name
+::make_row(PFS_account *account, PFS_instr_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ account->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_account.make_row(account))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_wait_visitor visitor(klass);
+ PFS_connection_iterator::visit_account(account, true, & visitor);
+
+ if (! account->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(wait_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_ews_by_account_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ case 1: /* HOST */
+ m_row.m_account.set_field(f->field_index, f);
+ break;
+ case 2: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 3, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 3, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_ews_by_account_by_event_name.h'
--- a/storage/perfschema/table_ews_by_account_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_ews_by_account_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,136 @@
+/* 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 */
+
+#ifndef TABLE_EWS_BY_ACCOUNT_BY_EVENT_NAME_H
+#define TABLE_EWS_BY_ACCOUNT_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_ews_by_account_by_event_name.h
+ Table EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_account.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME.
+*/
+struct row_ews_by_account_by_event_name
+{
+ /** Column USER, HOST. */
+ PFS_account_row m_account;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME.
+ Index 1 on user@host (0 based)
+ Index 2 on instrument view
+ Index 3 on instrument class (1 based)
+*/
+struct pos_ews_by_account_by_event_name
+: public PFS_triple_index, public PFS_instrument_view_constants
+{
+ pos_ews_by_account_by_event_name()
+ : PFS_triple_index(0, FIRST_VIEW, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= VIEW_MUTEX;
+ m_index_3= 1;
+ }
+
+ inline bool has_more_account(void)
+ { return (m_index_1 < account_max); }
+
+ inline void next_account(void)
+ {
+ m_index_1++;
+ m_index_2= FIRST_VIEW;
+ m_index_3= 1;
+ }
+
+ inline bool has_more_view(void)
+ { return (m_index_2 <= LAST_VIEW); }
+
+ inline void next_view(void)
+ {
+ m_index_2++;
+ m_index_3= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME. */
+class table_ews_by_account_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_ews_by_account_by_event_name();
+
+public:
+ ~table_ews_by_account_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_account *account, PFS_instr_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_ews_by_account_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_ews_by_account_by_event_name m_pos;
+ /** Next position. */
+ pos_ews_by_account_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/table_ews_by_host_by_event_name.cc'
--- a/storage/perfschema/table_ews_by_host_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_ews_by_host_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,273 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_ews_by_host_by_event_name.cc
+ Table EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_ews_by_host_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_account.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_ews_by_host_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_ews_by_host_by_event_name::m_field_def=
+{ 7, field_types };
+
+PFS_engine_table_share
+table_ews_by_host_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_waits_summary_by_host_by_event_name") },
+ &pfs_truncatable_acl,
+ table_ews_by_host_by_event_name::create,
+ NULL, /* write_row */
+ table_ews_by_host_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_ews_by_host_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_ews_by_host_by_event_name::create(void)
+{
+ return new table_ews_by_host_by_event_name();
+}
+
+int
+table_ews_by_host_by_event_name::delete_all_rows(void)
+{
+ reset_events_waits_by_thread();
+ reset_events_waits_by_account();
+ reset_events_waits_by_host();
+ return 0;
+}
+
+table_ews_by_host_by_event_name::table_ews_by_host_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_ews_by_host_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_ews_by_host_by_event_name::rnd_next(void)
+{
+ PFS_host *host;
+ PFS_instr_class *instr_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_host();
+ m_pos.next_host())
+ {
+ host= &host_array[m_pos.m_index_1];
+ if (host->m_lock.is_populated())
+ {
+ for ( ;
+ m_pos.has_more_view();
+ m_pos.next_view())
+ {
+ switch (m_pos.m_index_2)
+ {
+ case pos_ews_by_host_by_event_name::VIEW_MUTEX:
+ instr_class= find_mutex_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_RWLOCK:
+ instr_class= find_rwlock_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_COND:
+ instr_class= find_cond_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_FILE:
+ instr_class= find_file_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_TABLE:
+ instr_class= find_table_class(m_pos.m_index_3);
+ break;
+ default:
+ instr_class= NULL;
+ DBUG_ASSERT(false);
+ break;
+ }
+
+ if (instr_class)
+ {
+ make_row(host, instr_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_ews_by_host_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_host *host;
+ PFS_instr_class *instr_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < host_max);
+
+ host= &host_array[m_pos.m_index_1];
+ if (! host->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ switch (m_pos.m_index_2)
+ {
+ case pos_ews_by_host_by_event_name::VIEW_MUTEX:
+ instr_class= find_mutex_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_RWLOCK:
+ instr_class= find_rwlock_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_COND:
+ instr_class= find_cond_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_FILE:
+ instr_class= find_file_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_host_by_event_name::VIEW_TABLE:
+ instr_class= find_table_class(m_pos.m_index_3);
+ break;
+ default:
+ instr_class= NULL;
+ DBUG_ASSERT(false);
+ break;
+ }
+ if (instr_class)
+ {
+ make_row(host, instr_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_ews_by_host_by_event_name
+::make_row(PFS_host *host, PFS_instr_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ host->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_host.make_row(host))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_wait_visitor visitor(klass);
+ PFS_connection_iterator::visit_host(host, true, true, & visitor);
+
+ if (! host->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(wait_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_ews_by_host_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* HOST */
+ m_row.m_host.set_field(f);
+ break;
+ case 1: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 2, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_ews_by_host_by_event_name.h'
--- a/storage/perfschema/table_ews_by_host_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_ews_by_host_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,136 @@
+/* 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 */
+
+#ifndef TABLE_EWS_BY_HOST_BY_EVENT_NAME_H
+#define TABLE_EWS_BY_HOST_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_ews_by_host_by_event_name.h
+ Table EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_host.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME.
+*/
+struct row_ews_by_host_by_event_name
+{
+ /** Column HOST. */
+ PFS_host_row m_host;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME.
+ Index 1 on host (0 based)
+ Index 2 on instrument view
+ Index 3 on instrument class (1 based)
+*/
+struct pos_ews_by_host_by_event_name
+: public PFS_triple_index, public PFS_instrument_view_constants
+{
+ pos_ews_by_host_by_event_name()
+ : PFS_triple_index(0, FIRST_VIEW, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= FIRST_VIEW;
+ m_index_3= 1;
+ }
+
+ inline bool has_more_host(void)
+ { return (m_index_1 < host_max); }
+
+ inline void next_host(void)
+ {
+ m_index_1++;
+ m_index_2= FIRST_VIEW;
+ m_index_3= 1;
+ }
+
+ inline bool has_more_view(void)
+ { return (m_index_2 <= LAST_VIEW); }
+
+ inline void next_view(void)
+ {
+ m_index_2++;
+ m_index_3= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME. */
+class table_ews_by_host_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_ews_by_host_by_event_name();
+
+public:
+ ~table_ews_by_host_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_host *host, PFS_instr_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_ews_by_host_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_ews_by_host_by_event_name m_pos;
+ /** Next position. */
+ pos_ews_by_host_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== added file 'storage/perfschema/table_ews_by_user_by_event_name.cc'
--- a/storage/perfschema/table_ews_by_user_by_event_name.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_ews_by_user_by_event_name.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,273 @@
+/* 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 */
+
+/**
+ @file storage/perfschema/table_ews_by_user_by_event_name.cc
+ Table EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME (implementation).
+*/
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "pfs_instr_class.h"
+#include "pfs_column_types.h"
+#include "pfs_column_values.h"
+#include "table_ews_by_user_by_event_name.h"
+#include "pfs_global.h"
+#include "pfs_account.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_ews_by_user_by_event_name::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("EVENT_NAME") },
+ { C_STRING_WITH_LEN("varchar(128)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("COUNT_STAR") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_ews_by_user_by_event_name::m_field_def=
+{ 7, field_types };
+
+PFS_engine_table_share
+table_ews_by_user_by_event_name::m_share=
+{
+ { C_STRING_WITH_LEN("events_waits_summary_by_user_by_event_name") },
+ &pfs_truncatable_acl,
+ table_ews_by_user_by_event_name::create,
+ NULL, /* write_row */
+ table_ews_by_user_by_event_name::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(pos_ews_by_user_by_event_name),
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table*
+table_ews_by_user_by_event_name::create(void)
+{
+ return new table_ews_by_user_by_event_name();
+}
+
+int
+table_ews_by_user_by_event_name::delete_all_rows(void)
+{
+ reset_events_waits_by_thread();
+ reset_events_waits_by_account();
+ reset_events_waits_by_user();
+ return 0;
+}
+
+table_ews_by_user_by_event_name::table_ews_by_user_by_event_name()
+ : PFS_engine_table(&m_share, &m_pos),
+ m_row_exists(false), m_pos(), m_next_pos()
+{}
+
+void table_ews_by_user_by_event_name::reset_position(void)
+{
+ m_pos.reset();
+ m_next_pos.reset();
+}
+
+int table_ews_by_user_by_event_name::rnd_next(void)
+{
+ PFS_user *user;
+ PFS_instr_class *instr_class;
+
+ for (m_pos.set_at(&m_next_pos);
+ m_pos.has_more_user();
+ m_pos.next_user())
+ {
+ user= &user_array[m_pos.m_index_1];
+ if (user->m_lock.is_populated())
+ {
+ for ( ;
+ m_pos.has_more_view();
+ m_pos.next_view())
+ {
+ switch (m_pos.m_index_2)
+ {
+ case pos_ews_by_user_by_event_name::VIEW_MUTEX:
+ instr_class= find_mutex_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_RWLOCK:
+ instr_class= find_rwlock_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_COND:
+ instr_class= find_cond_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_FILE:
+ instr_class= find_file_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_TABLE:
+ instr_class= find_table_class(m_pos.m_index_3);
+ break;
+ default:
+ instr_class= NULL;
+ DBUG_ASSERT(false);
+ break;
+ }
+
+ if (instr_class)
+ {
+ make_row(user, instr_class);
+ m_next_pos.set_after(&m_pos);
+ return 0;
+ }
+ }
+ }
+ }
+
+ return HA_ERR_END_OF_FILE;
+}
+
+int
+table_ews_by_user_by_event_name::rnd_pos(const void *pos)
+{
+ PFS_user *user;
+ PFS_instr_class *instr_class;
+
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index_1 < user_max);
+
+ user= &user_array[m_pos.m_index_1];
+ if (! user->m_lock.is_populated())
+ return HA_ERR_RECORD_DELETED;
+
+ switch (m_pos.m_index_2)
+ {
+ case pos_ews_by_user_by_event_name::VIEW_MUTEX:
+ instr_class= find_mutex_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_RWLOCK:
+ instr_class= find_rwlock_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_COND:
+ instr_class= find_cond_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_FILE:
+ instr_class= find_file_class(m_pos.m_index_3);
+ break;
+ case pos_ews_by_user_by_event_name::VIEW_TABLE:
+ instr_class= find_table_class(m_pos.m_index_3);
+ break;
+ default:
+ instr_class= NULL;
+ DBUG_ASSERT(false);
+ break;
+ }
+ if (instr_class)
+ {
+ make_row(user, instr_class);
+ return 0;
+ }
+
+ return HA_ERR_RECORD_DELETED;
+}
+
+void table_ews_by_user_by_event_name
+::make_row(PFS_user *user, PFS_instr_class *klass)
+{
+ pfs_lock lock;
+ m_row_exists= false;
+
+ user->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_user.make_row(user))
+ return;
+
+ m_row.m_event_name.make_row(klass);
+
+ PFS_connection_wait_visitor visitor(klass);
+ PFS_connection_iterator::visit_user(user, true, true, & visitor);
+
+ if (! user->m_lock.end_optimistic_lock(&lock))
+ return;
+
+ m_row_exists= true;
+
+ time_normalizer *normalizer= time_normalizer::get(wait_timer);
+ m_row.m_stat.set(normalizer, & visitor.m_stat);
+}
+
+int table_ews_by_user_by_event_name
+::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ m_row.m_user.set_field(f);
+ break;
+ case 1: /* EVENT_NAME */
+ m_row.m_event_name.set_field(f);
+ break;
+ default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */
+ m_row.m_stat.set_field(f->field_index - 2, f);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
=== added file 'storage/perfschema/table_ews_by_user_by_event_name.h'
--- a/storage/perfschema/table_ews_by_user_by_event_name.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_ews_by_user_by_event_name.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,136 @@
+/* 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 */
+
+#ifndef TABLE_EWS_BY_USER_BY_EVENT_NAME_H
+#define TABLE_EWS_BY_USER_BY_EVENT_NAME_H
+
+/**
+ @file storage/perfschema/table_ews_by_user_by_event_name.h
+ Table EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_user.h"
+#include "table_helper.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of table
+ PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME.
+*/
+struct row_ews_by_user_by_event_name
+{
+ /** Column USER. */
+ PFS_user_row m_user;
+ /** Column EVENT_NAME. */
+ PFS_event_name_row m_event_name;
+ /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */
+ PFS_stat_row m_stat;
+};
+
+/**
+ Position of a cursor on
+ PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME.
+ Index 1 on user (0 based)
+ Index 2 on instrument view
+ Index 3 on instrument class (1 based)
+*/
+struct pos_ews_by_user_by_event_name
+: public PFS_triple_index, public PFS_instrument_view_constants
+{
+ pos_ews_by_user_by_event_name()
+ : PFS_triple_index(0, FIRST_VIEW, 1)
+ {}
+
+ inline void reset(void)
+ {
+ m_index_1= 0;
+ m_index_2= FIRST_VIEW;
+ m_index_3= 1;
+ }
+
+ inline bool has_more_user(void)
+ { return (m_index_1 < user_max); }
+
+ inline void next_user(void)
+ {
+ m_index_1++;
+ m_index_2= FIRST_VIEW;
+ m_index_3= 1;
+ }
+
+ inline bool has_more_view(void)
+ { return (m_index_2 <= LAST_VIEW); }
+
+ inline void next_view(void)
+ {
+ m_index_2++;
+ m_index_3= 1;
+ }
+};
+
+/** Table PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME. */
+class table_ews_by_user_by_event_name : public PFS_engine_table
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+ table_ews_by_user_by_event_name();
+
+public:
+ ~table_ews_by_user_by_event_name()
+ {}
+
+protected:
+ void make_row(PFS_user *user, PFS_instr_class *klass);
+
+private:
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_ews_by_user_by_event_name m_row;
+ /** True is the current row exists. */
+ bool m_row_exists;
+ /** Current position. */
+ pos_ews_by_user_by_event_name m_pos;
+ /** Next position. */
+ pos_ews_by_user_by_event_name m_next_pos;
+};
+
+/** @} */
+#endif
=== modified file 'storage/perfschema/table_helper.cc'
--- a/storage/perfschema/table_helper.cc 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/table_helper.cc 2011-05-07 00:40:25 +0000
@@ -22,6 +22,84 @@
#include "my_pthread.h"
#include "pfs_engine_table.h"
#include "table_helper.h"
+#include "pfs_host.h"
+#include "pfs_user.h"
+#include "pfs_account.h"
+
+int PFS_host_row::make_row(PFS_host *pfs)
+{
+ m_hostname_length= pfs->m_hostname_length;
+ if (m_hostname_length > sizeof(m_hostname))
+ return 1;
+ if (m_hostname_length > 0)
+ memcpy(m_hostname, pfs->m_hostname, sizeof(m_hostname));
+ return 0;
+}
+
+void PFS_host_row::set_field(Field *f)
+{
+ if (m_hostname_length > 0)
+ PFS_engine_table::set_field_char_utf8(f, m_hostname, m_hostname_length);
+ else
+ f->set_null();
+}
+
+int PFS_user_row::make_row(PFS_user *pfs)
+{
+ m_username_length= pfs->m_username_length;
+ if (m_username_length > sizeof(m_username))
+ return 1;
+ if (m_username_length > 0)
+ memcpy(m_username, pfs->m_username, sizeof(m_username));
+ return 0;
+}
+
+void PFS_user_row::set_field(Field *f)
+{
+ if (m_username_length > 0)
+ PFS_engine_table::set_field_char_utf8(f, m_username, m_username_length);
+ else
+ f->set_null();
+}
+
+int PFS_account_row::make_row(PFS_account *pfs)
+{
+ m_username_length= pfs->m_username_length;
+ if (m_username_length > sizeof(m_username))
+ return 1;
+ if (m_username_length > 0)
+ memcpy(m_username, pfs->m_username, sizeof(m_username));
+
+ m_hostname_length= pfs->m_hostname_length;
+ if (m_hostname_length > sizeof(m_hostname))
+ return 1;
+ if (m_hostname_length > 0)
+ memcpy(m_hostname, pfs->m_hostname, sizeof(m_hostname));
+
+ return 0;
+}
+
+void PFS_account_row::set_field(uint index, Field *f)
+{
+ switch (index)
+ {
+ case 0: /* USER */
+ if (m_username_length > 0)
+ PFS_engine_table::set_field_char_utf8(f, m_username, m_username_length);
+ else
+ f->set_null();
+ break;
+ case 1: /* HOST */
+ if (m_hostname_length > 0)
+ PFS_engine_table::set_field_char_utf8(f, m_hostname, m_hostname_length);
+ else
+ f->set_null();
+ break;
+ default:
+ DBUG_ASSERT(false);
+ break;
+ }
+}
int PFS_object_row::make_row(PFS_table_share *pfs)
{
@@ -173,6 +251,22 @@ void PFS_statement_stat_row::set_field(u
}
}
+void PFS_connection_stat_row::set_field(uint index, Field *f)
+{
+ switch (index)
+ {
+ case 0: /* CURRENT_CONNECTIONS */
+ PFS_engine_table::set_field_ulonglong(f, m_current_connections);
+ break;
+ case 1: /* TOTAL_CONNECTIONS */
+ PFS_engine_table::set_field_ulonglong(f, m_total_connections);
+ break;
+ default:
+ DBUG_ASSERT(false);
+ break;
+ }
+}
+
void set_field_object_type(Field *f, enum_object_type object_type)
{
switch (object_type)
=== modified file 'storage/perfschema/table_helper.h'
--- a/storage/perfschema/table_helper.h 2011-02-14 14:23:55 +0000
+++ b/storage/perfschema/table_helper.h 2011-05-07 00:40:25 +0000
@@ -22,6 +22,10 @@
#include "pfs_engine_table.h"
#include "pfs_instr_class.h"
+struct PFS_host;
+struct PFS_user;
+struct PFS_account;
+
/**
@file storage/perfschema/table_helper.h
Performance schema table helpers (declarations).
@@ -57,6 +61,52 @@ struct PFS_object_view_constants
static const uint VIEW_FUNCTION= 4;
};
+/** Row fragment for column HOST. */
+struct PFS_host_row
+{
+ /** Column HOST. */
+ char m_hostname[HOSTNAME_LENGTH];
+ /** Length in bytes of @c m_hostname. */
+ uint m_hostname_length;
+
+ /** Build a row from a memory buffer. */
+ int make_row(PFS_host *pfs);
+ /** Set a table field from the row. */
+ void set_field(Field *f);
+};
+
+/** Row fragment for column USER. */
+struct PFS_user_row
+{
+ /** Column USER. */
+ char m_username[USERNAME_LENGTH];
+ /** Length in bytes of @c m_username. */
+ uint m_username_length;
+
+ /** Build a row from a memory buffer. */
+ int make_row(PFS_user *pfs);
+ /** Set a table field from the row. */
+ void set_field(Field *f);
+};
+
+/** Row fragment for columns USER, HOST. */
+struct PFS_account_row
+{
+ /** Column USER. */
+ char m_username[USERNAME_LENGTH];
+ /** Length in bytes of @c m_username. */
+ uint m_username_length;
+ /** Column HOST. */
+ char m_hostname[HOSTNAME_LENGTH];
+ /** Length in bytes of @c m_hostname. */
+ uint m_hostname_length;
+
+ /** Build a row from a memory buffer. */
+ int make_row(PFS_account *pfs);
+ /** Set a table field from the row. */
+ void set_field(uint index, Field *f);
+};
+
/** Row fragment for column EVENT_NAME. */
struct PFS_event_name_row
{
@@ -346,6 +396,21 @@ struct PFS_statement_stat_row
void set_field(uint index, Field *f);
};
+struct PFS_connection_stat_row
+{
+ ulonglong m_current_connections;
+ ulonglong m_total_connections;
+
+ inline void set(const PFS_connection_stat *stat)
+ {
+ m_current_connections= stat->m_current_connections;
+ m_total_connections= stat->m_total_connections;
+ }
+
+ /** Set a table field from the row. */
+ void set_field(uint index, Field *f);
+};
+
void set_field_object_type(Field *f, enum_object_type object_type);
/** @} */
=== added file 'storage/perfschema/table_hosts.cc'
--- a/storage/perfschema/table_hosts.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_hosts.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,145 @@
+/* Copyright (c) 2011, 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "table_hosts.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_host.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_hosts::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("HOST") },
+ { C_STRING_WITH_LEN("char(60)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("CURRENT_CONNECTIONS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("TOTAL_CONNECTIONS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_hosts::m_field_def=
+{ 3, field_types };
+
+PFS_engine_table_share
+table_hosts::m_share=
+{
+ { C_STRING_WITH_LEN("hosts") },
+ &pfs_truncatable_acl,
+ &table_hosts::create,
+ NULL, /* write_row */
+ table_hosts::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(PFS_simple_index), /* ref length */
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table* table_hosts::create()
+{
+ return new table_hosts();
+}
+
+int
+table_hosts::delete_all_rows(void)
+{
+ reset_events_waits_by_thread();
+ reset_events_waits_by_account();
+ reset_events_waits_by_host();
+ reset_events_stages_by_thread();
+ reset_events_stages_by_account();
+ reset_events_stages_by_host();
+ reset_events_statements_by_thread();
+ reset_events_statements_by_account();
+ reset_events_statements_by_host();
+ purge_all_host();
+ return 0;
+}
+
+table_hosts::table_hosts()
+ : cursor_by_host(& m_share),
+ m_row_exists(false)
+{}
+
+void table_hosts::make_row(PFS_host *pfs)
+{
+ pfs_lock lock;
+
+ m_row_exists= false;
+ pfs->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_host.make_row(pfs))
+ return;
+
+ PFS_connection_stat_visitor visitor;
+ PFS_connection_iterator::visit_host(pfs, true, true, & visitor);
+
+ if (! pfs->m_lock.end_optimistic_lock(& lock))
+ return;
+
+ m_row.m_connection_stat.set(& visitor.m_stat);
+ m_row_exists= true;
+}
+
+int table_hosts::read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* HOST */
+ m_row.m_host.set_field(f);
+ break;
+ case 1: /* CURRENT_CONNECTIONS */
+ case 2: /* TOTAL_CONNECTIONS */
+ m_row.m_connection_stat.set_field(f->field_index - 1, f);
+ break;
+ default:
+ DBUG_ASSERT(false);
+ }
+ }
+ }
+ return 0;
+}
+
=== added file 'storage/perfschema/table_hosts.h'
--- a/storage/perfschema/table_hosts.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_hosts.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,80 @@
+/* Copyright (c) 2011, 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef TABLE_HOSTS_H
+#define TABLE_HOSTS_H
+
+#include "pfs_column_types.h"
+#include "cursor_by_host.h"
+#include "table_helper.h"
+
+struct PFS_host;
+
+/**
+ \addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of PERFORMANCE_SCHEMA.HOSTS.
+*/
+struct row_hosts
+{
+ /** Column HOST. */
+ PFS_host_row m_host;
+ /** Columns CURRENT_CONNECTIONS, TOTAL_CONNECTIONS. */
+ PFS_connection_stat_row m_connection_stat;
+};
+
+/** Table PERFORMANCE_SCHEMA.THREADS. */
+class table_hosts : public cursor_by_host
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ /** Table builder */
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+
+protected:
+ table_hosts();
+
+public:
+ ~table_hosts()
+ {}
+
+private:
+ virtual void make_row(PFS_host *pfs);
+
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_hosts m_row;
+ /** True if the current row exists. */
+ bool m_row_exists;
+};
+
+/** @} */
+#endif
=== modified file 'storage/perfschema/table_threads.cc'
--- a/storage/perfschema/table_threads.cc 2010-12-02 08:07:06 +0000
+++ b/storage/perfschema/table_threads.cc 2011-05-07 00:40:25 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2011, 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
@@ -122,52 +122,10 @@ PFS_engine_table* table_threads::create(
}
table_threads::table_threads()
- : PFS_engine_table(& m_share, & m_pos),
- m_row_exists(false), m_pos(0), m_next_pos(0)
+ : cursor_by_thread(& m_share),
+ m_row_exists(false)
{}
-void table_threads::reset_position(void)
-{
- m_pos.m_index= 0;
- m_next_pos.m_index= 0;
-}
-
-int table_threads::rnd_next()
-{
- PFS_thread *pfs;
-
- for (m_pos.set_at(&m_next_pos);
- m_pos.m_index < thread_max;
- m_pos.next())
- {
- pfs= &thread_array[m_pos.m_index];
- if (pfs->m_lock.is_populated())
- {
- make_row(pfs);
- m_next_pos.set_after(&m_pos);
- return 0;
- }
- }
-
- return HA_ERR_END_OF_FILE;
-}
-
-int table_threads::rnd_pos(const void *pos)
-{
- PFS_thread *pfs;
-
- set_position(pos);
- DBUG_ASSERT(m_pos.m_index < thread_max);
- pfs= &thread_array[m_pos.m_index];
- if (pfs->m_lock.is_populated())
- {
- make_row(pfs);
- return 0;
- }
-
- return HA_ERR_RECORD_DELETED;
-}
-
void table_threads::make_row(PFS_thread *pfs)
{
pfs_lock lock;
=== modified file 'storage/perfschema/table_threads.h'
--- a/storage/perfschema/table_threads.h 2010-07-21 19:06:21 +0000
+++ b/storage/perfschema/table_threads.h 2011-05-07 00:40:25 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2011, 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
@@ -17,7 +17,7 @@
#define TABLE_THREADS_H
#include "pfs_column_types.h"
-#include "pfs_engine_table.h"
+#include "cursor_by_thread.h"
struct PFS_thread;
@@ -70,7 +70,7 @@ struct row_threads
};
/** Table PERFORMANCE_SCHEMA.THREADS. */
-class table_threads : public PFS_engine_table
+class table_threads : public cursor_by_thread
{
public:
/** Table share */
@@ -78,10 +78,6 @@ public:
/** Table builder */
static PFS_engine_table* create();
- virtual int rnd_next();
- virtual int rnd_pos(const void *pos);
- virtual void reset_position(void);
-
protected:
virtual int read_row_values(TABLE *table,
unsigned char *buf,
@@ -102,7 +98,7 @@ public:
{}
private:
- void make_row(PFS_thread *pfs);
+ virtual void make_row(PFS_thread *pfs);
/** Table share lock. */
static THR_LOCK m_table_lock;
@@ -113,10 +109,6 @@ private:
row_threads m_row;
/** True if the current row exists. */
bool m_row_exists;
- /** Current position. */
- PFS_simple_index m_pos;
- /** Next position. */
- PFS_simple_index m_next_pos;
};
/** @} */
=== added file 'storage/perfschema/table_users.cc'
--- a/storage/perfschema/table_users.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_users.cc 2011-05-07 00:40:25 +0000
@@ -0,0 +1,145 @@
+/* Copyright (c) 2011, 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#include "my_global.h"
+#include "my_pthread.h"
+#include "table_users.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "pfs_user.h"
+#include "pfs_visitor.h"
+
+THR_LOCK table_users::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("USER") },
+ { C_STRING_WITH_LEN("char(16)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("CURRENT_CONNECTIONS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ },
+ {
+ { C_STRING_WITH_LEN("TOTAL_CONNECTIONS") },
+ { C_STRING_WITH_LEN("bigint(20)") },
+ { NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_users::m_field_def=
+{ 3, field_types };
+
+PFS_engine_table_share
+table_users::m_share=
+{
+ { C_STRING_WITH_LEN("users") },
+ &pfs_truncatable_acl,
+ &table_users::create,
+ NULL, /* write_row */
+ table_users::delete_all_rows,
+ NULL, /* get_row_count */
+ 1000, /* records */
+ sizeof(PFS_simple_index), /* ref length */
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table* table_users::create()
+{
+ return new table_users();
+}
+
+int
+table_users::delete_all_rows(void)
+{
+ reset_events_waits_by_thread();
+ reset_events_waits_by_account();
+ reset_events_waits_by_user();
+ reset_events_stages_by_thread();
+ reset_events_stages_by_account();
+ reset_events_stages_by_user();
+ reset_events_statements_by_thread();
+ reset_events_statements_by_account();
+ reset_events_statements_by_user();
+ purge_all_user();
+ return 0;
+}
+
+table_users::table_users()
+ : cursor_by_user(& m_share),
+ m_row_exists(false)
+{}
+
+void table_users::make_row(PFS_user *pfs)
+{
+ pfs_lock lock;
+
+ m_row_exists= false;
+ pfs->m_lock.begin_optimistic_lock(&lock);
+
+ if (m_row.m_user.make_row(pfs))
+ return;
+
+ PFS_connection_stat_visitor visitor;
+ PFS_connection_iterator::visit_user(pfs, true, true, & visitor);
+
+ if (! pfs->m_lock.end_optimistic_lock(& lock))
+ return;
+
+ m_row.m_connection_stat.set(& visitor.m_stat);
+ m_row_exists= true;
+}
+
+int table_users::read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ if (unlikely(! m_row_exists))
+ return HA_ERR_RECORD_DELETED;
+
+ /* Set the null bits */
+ DBUG_ASSERT(table->s->null_bytes == 1);
+ buf[0]= 0;
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ switch(f->field_index)
+ {
+ case 0: /* USER */
+ m_row.m_user.set_field(f);
+ break;
+ case 1: /* CURRENT_CONNECTIONS */
+ case 2: /* TOTAL_CONNECTIONS */
+ m_row.m_connection_stat.set_field(f->field_index - 1, f);
+ break;
+ default:
+ DBUG_ASSERT(false);
+ }
+ }
+ }
+ return 0;
+}
+
=== added file 'storage/perfschema/table_users.h'
--- a/storage/perfschema/table_users.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_users.h 2011-05-07 00:40:25 +0000
@@ -0,0 +1,80 @@
+/* Copyright (c) 2011, 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef TABLE_USERS_H
+#define TABLE_USERS_H
+
+#include "pfs_column_types.h"
+#include "cursor_by_user.h"
+#include "table_helper.h"
+
+struct PFS_user;
+
+/**
+ \addtogroup Performance_schema_tables
+ @{
+*/
+
+/**
+ A row of PERFORMANCE_SCHEMA.USERS.
+*/
+struct row_users
+{
+ /** Column USER. */
+ PFS_user_row m_user;
+ /** Columns CURRENT_CONNECTIONS, TOTAL_CONNECTIONS. */
+ PFS_connection_stat_row m_connection_stat;
+};
+
+/** Table PERFORMANCE_SCHEMA.USERS. */
+class table_users : public cursor_by_user
+{
+public:
+ /** Table share */
+ static PFS_engine_table_share m_share;
+ /** Table builder */
+ static PFS_engine_table* create();
+ static int delete_all_rows();
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+
+protected:
+ table_users();
+
+public:
+ ~table_users()
+ {}
+
+private:
+ virtual void make_row(PFS_user *pfs);
+
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+
+ /** Current row. */
+ row_users m_row;
+ /** True if the current row exists. */
+ bool m_row_exists;
+};
+
+/** @} */
+#endif
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (marc.alff:3347 to 3348) WL#5378 | Marc Alff | 7 May |