From: Marc Alff Date: January 7 2011 4:21pm Subject: bzr push into mysql-trunk-wl5379 branch (marc.alff:3214 to 3215) WL#5371 WL#5379 WL#5420 List-Archive: http://lists.mysql.com/commits/128188 Message-Id: <201101071621.p078gE2o012490@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3215 Marc Alff 2011-01-07 WL#5371 PERFORMANCE_SCHEMA Instrumenting Table Locks WL#5379 PERFORMANCE SCHEMA TABLE / INDEX IO SUMMARY WL#5420 PERFORMANCE SCHEMA TABLE LOCK WAIT SUMMARY Code cleanup, implemented a visitor pattern to reduce code duplication. added: storage/perfschema/pfs_visitor.cc storage/perfschema/pfs_visitor.h modified: storage/perfschema/CMakeLists.txt storage/perfschema/table_ews_by_thread_by_event_name.cc storage/perfschema/table_ews_by_thread_by_event_name.h storage/perfschema/table_ews_global_by_event_name.cc storage/perfschema/table_ews_global_by_event_name.h storage/perfschema/table_helper.cc storage/perfschema/table_helper.h storage/perfschema/table_tiws_by_index_usage.cc storage/perfschema/table_tiws_by_index_usage.h storage/perfschema/table_tiws_by_table.cc storage/perfschema/table_tiws_by_table.h storage/perfschema/table_tlws_by_table.cc storage/perfschema/table_tlws_by_table.h 3214 Marc Alff 2011-01-06 [merge] Merge mysql-trunk --> mysql-trunk-wl5379 removed: include/my_no_pthread.h mysys/mf_brkhant.c modified: client/mysqladmin.cc cmd-line-utils/readline/CMakeLists.txt config.h.cmake dbug/dbug.c dbug/dbug_analyze.c dbug/my_main.c dbug/tests.c include/CMakeLists.txt include/heap.h include/my_base.h include/my_bitmap.h include/my_global.h include/my_pthread.h include/my_sys.h include/myisam.h include/thr_alarm.h libmysql/client_settings.h libmysql/libmysql.c mysql-test/collections/default.experimental mysql-test/collections/mysql-trunk.weekly mysql-test/r/auto_increment.result mysql-test/r/myisam_mrr_all.result mysql-test/r/myisam_mrr_cost_all.result mysql-test/r/order_by_all.result mysql-test/r/select_all.result mysql-test/r/select_all_jcl6.result mysql-test/r/select_icp_mrr_jcl6.result mysql-test/r/select_none_jcl6.result mysql-test/r/show_check.result mysql-test/suite/engines/funcs/r/db_alter_character_set.result mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result mysql-test/suite/engines/funcs/r/in_multicolumn_string_pk_constraint_error.result mysql-test/suite/engines/funcs/r/in_multicolumn_string_pk_constraint_ignore.result mysql-test/suite/engines/funcs/r/in_multicolumn_string_unique_constraint_error.result mysql-test/suite/engines/funcs/r/in_string_pk_constraint_error.result mysql-test/suite/engines/funcs/r/in_string_unique_constraint_error.result mysql-test/suite/engines/funcs/r/rpl000013.result mysql-test/suite/engines/funcs/r/rpl_000015.result mysql-test/suite/engines/funcs/r/rpl_change_master.result mysql-test/suite/engines/funcs/r/rpl_drop.result mysql-test/suite/engines/funcs/r/rpl_flushlog_loop.result mysql-test/suite/engines/funcs/r/rpl_loaddata_s.result mysql-test/suite/engines/funcs/r/rpl_log_pos.result mysql-test/suite/engines/funcs/r/rpl_rbr_to_sbr.result mysql-test/suite/engines/funcs/r/rpl_row_drop.result mysql-test/suite/engines/funcs/r/rpl_row_inexist_tbl.result mysql-test/suite/engines/funcs/r/rpl_row_reset_slave.result mysql-test/suite/engines/funcs/r/rpl_row_sp005.result mysql-test/suite/engines/funcs/r/rpl_row_trig003.result mysql-test/suite/engines/funcs/r/rpl_row_until.result mysql-test/suite/engines/funcs/r/rpl_server_id1.result mysql-test/suite/engines/funcs/r/rpl_server_id2.result mysql-test/suite/engines/funcs/r/rpl_session_var.result mysql-test/suite/engines/funcs/r/rpl_slave_status.result mysql-test/suite/engines/funcs/r/rpl_stm_no_op.result mysql-test/suite/engines/funcs/r/rpl_switch_stm_row_mixed.result mysql-test/suite/engines/funcs/r/rpl_temp_table.result mysql-test/suite/engines/funcs/r/rpl_trigger.result mysql-test/suite/engines/funcs/r/se_join_left.result mysql-test/suite/engines/funcs/r/se_join_left_outer.result mysql-test/suite/engines/funcs/r/se_join_natural_left.result mysql-test/suite/engines/funcs/r/se_join_natural_left_outer.result mysql-test/suite/engines/funcs/r/sf_alter.result mysql-test/suite/engines/funcs/r/sf_cursor.result mysql-test/suite/engines/funcs/r/sp_alter.result mysql-test/suite/engines/funcs/r/sp_cursor.result mysql-test/suite/engines/funcs/r/ta_rename.result mysql-test/suite/engines/funcs/t/db_alter_collate_utf8.test mysql-test/suite/engines/funcs/t/disabled.def mysql-test/suite/engines/funcs/t/in_multicolumn_string_pk_constraint_error.test mysql-test/suite/engines/funcs/t/in_multicolumn_string_pk_constraint_ignore.test mysql-test/suite/engines/funcs/t/in_multicolumn_string_unique_constraint_error.test mysql-test/suite/engines/funcs/t/in_string_pk_constraint_error.test mysql-test/suite/engines/funcs/t/in_string_unique_constraint_error.test mysql-test/suite/engines/funcs/t/rpl000013.test mysql-test/suite/engines/funcs/t/rpl_000015.test mysql-test/suite/engines/funcs/t/rpl_change_master.test mysql-test/suite/engines/funcs/t/rpl_err_ignoredtable.test mysql-test/suite/engines/funcs/t/rpl_flushlog_loop.test mysql-test/suite/engines/funcs/t/rpl_get_lock.test mysql-test/suite/engines/funcs/t/rpl_loaddata_s.test mysql-test/suite/engines/funcs/t/rpl_loadfile.test mysql-test/suite/engines/funcs/t/rpl_log_pos.test mysql-test/suite/engines/funcs/t/rpl_misc_functions.test mysql-test/suite/engines/funcs/t/rpl_rbr_to_sbr.test mysql-test/suite/engines/funcs/t/rpl_row_drop.test mysql-test/suite/engines/funcs/t/rpl_row_inexist_tbl.test mysql-test/suite/engines/funcs/t/rpl_row_until.test mysql-test/suite/engines/funcs/t/rpl_server_id1.test mysql-test/suite/engines/funcs/t/rpl_server_id2.test mysql-test/suite/engines/funcs/t/rpl_slave_status.test mysql-test/suite/engines/funcs/t/rpl_switch_stm_row_mixed.test mysql-test/suite/engines/funcs/t/rpl_temp_table.test mysql-test/suite/engines/funcs/t/rpl_temporary.test mysql-test/suite/engines/funcs/t/rpl_trigger.test mysql-test/suite/engines/funcs/t/se_join_left.test mysql-test/suite/engines/funcs/t/se_join_left_outer.test mysql-test/suite/engines/funcs/t/se_join_natural_left.test mysql-test/suite/engines/funcs/t/se_join_natural_left_outer.test mysql-test/suite/engines/iuds/r/insert_number.result mysql-test/suite/engines/iuds/r/strings_charsets_update_delete.result mysql-test/suite/engines/iuds/r/strings_update_delete.result mysql-test/suite/engines/iuds/r/type_bit_iuds.result mysql-test/suite/engines/iuds/r/update_delete_calendar.result mysql-test/suite/engines/iuds/r/update_delete_number.result mysql-test/suite/engines/iuds/t/disabled.def mysql-test/suite/engines/iuds/t/insert_number.test mysql-test/suite/engines/iuds/t/update_delete_calendar.test mysql-test/suite/perfschema/include/binlog_common.inc mysql-test/suite/perfschema/r/binlog_mix.result mysql-test/suite/perfschema/r/binlog_row.result mysql-test/suite/perfschema/r/binlog_stmt.result mysql-test/suite/perfschema/t/binlog_mix.test mysql-test/suite/perfschema/t/binlog_row.test mysql-test/suite/perfschema/t/binlog_stmt.test mysql-test/t/auto_increment.test mysql-test/t/show_check.test mysys/mf_iocache.c mysys/mf_iocache2.c mysys/mf_keycache.c mysys/mf_keycaches.c mysys/my_bitmap.c mysys/my_fstream.c mysys/my_gethostbyname.c mysys/my_init.c mysys/my_lib.c mysys/my_open.c mysys/my_pread.c mysys/my_pthread.c mysys/my_read.c mysys/my_static.c mysys/my_thr_init.c mysys/my_write.c mysys/mysys_priv.h mysys/thr_alarm.c mysys/thr_lock.c mysys/thr_mutex.c mysys/thr_rwlock.c sql-common/client.c sql-common/client_plugin.c sql/client_settings.h sql/filesort.cc sql/ha_partition.cc sql/sql_show.cc storage/heap/heapdef.h storage/heap/hp_block.c storage/heap/hp_create.c storage/heap/hp_open.c storage/heap/hp_static.c storage/heap/hp_test2.c storage/innobase/handler/ha_innodb.cc storage/myisam/ha_myisam.cc storage/myisam/mi_check.c storage/myisam/mi_close.c storage/myisam/mi_delete.c storage/myisam/mi_delete_all.c storage/myisam/mi_dynrec.c storage/myisam/mi_log.c storage/myisam/mi_open.c storage/myisam/mi_static.c storage/myisam/mi_statrec.c storage/myisam/mi_update.c storage/myisam/mi_write.c storage/myisam/myisamdef.h storage/myisam/sort.c storage/myisammrg/myrg_def.h tests/thread_test.c === modified file 'storage/perfschema/CMakeLists.txt' --- a/storage/perfschema/CMakeLists.txt 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/CMakeLists.txt 2011-01-07 16:20:19 +0000 @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 @@ -21,78 +21,84 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ADD_DEFINITIONS(-DMYSQL_SERVER) +# +# Maintainer: keep this list sorted, to avoid merge collisions. +# Tip: ls -1 *.h, ls -1 *.cc +# SET(PERFSCHEMA_SOURCES ha_perfschema.h - pfs_column_types.h - pfs_column_values.h - pfs_defaults.h - pfs_events_waits.h - pfs_global.h - pfs.h - pfs_instr.h - pfs_instr_class.h - pfs_lock.h - pfs_atomic.h - pfs_server.h - pfs_setup_actor.h - pfs_setup_object.h - pfs_stat.h - pfs_engine_table.h - pfs_timer.h - table_all_instr.h - table_events_waits.h - table_events_waits_summary.h - table_ews_by_thread_by_event_name.h - table_ews_global_by_event_name.h - table_file_instances.h - table_file_summary.h - table_helper.h - table_os_global_by_type.h - table_performance_timers.h - table_setup_actors.h - table_setup_consumers.h - table_setup_instruments.h - table_setup_objects.h - table_setup_timers.h - table_sync_instances.h - table_threads.h - table_tiws_by_index_usage.h - table_tiws_by_table.h - table_tlws_by_table.h - ha_perfschema.cc - pfs.cc - pfs_column_values.cc - pfs_defaults.cc - pfs_events_waits.cc - pfs_global.cc - pfs_instr.cc - pfs_instr_class.cc - pfs_server.cc - pfs_setup_actor.cc - pfs_setup_object.cc - pfs_engine_table.cc - pfs_timer.cc - table_all_instr.cc - table_events_waits.cc - table_events_waits_summary.cc - table_ews_by_thread_by_event_name.cc - table_ews_global_by_event_name.cc - table_file_instances.cc - table_file_summary.cc - table_helper.cc - table_os_global_by_type.cc - table_performance_timers.cc - table_setup_actors.cc - table_setup_consumers.cc - table_setup_instruments.cc - table_setup_objects.cc - table_setup_timers.cc - table_sync_instances.cc - table_threads.cc - table_tiws_by_index_usage.cc - table_tiws_by_table.cc - table_tlws_by_table.cc - pfs_atomic.cc - pfs_check.cc +pfs.h +pfs_atomic.h +pfs_column_types.h +pfs_column_values.h +pfs_defaults.h +pfs_engine_table.h +pfs_events_waits.h +pfs_global.h +pfs_instr.h +pfs_instr_class.h +pfs_lock.h +pfs_server.h +pfs_setup_actor.h +pfs_setup_object.h +pfs_stat.h +pfs_timer.h +pfs_visitor.h +table_all_instr.h +table_events_waits.h +table_events_waits_summary.h +table_ews_by_thread_by_event_name.h +table_ews_global_by_event_name.h +table_file_instances.h +table_file_summary.h +table_helper.h +table_os_global_by_type.h +table_performance_timers.h +table_setup_actors.h +table_setup_consumers.h +table_setup_instruments.h +table_setup_objects.h +table_setup_timers.h +table_sync_instances.h +table_threads.h +table_tiws_by_index_usage.h +table_tiws_by_table.h +table_tlws_by_table.h +ha_perfschema.cc +pfs.cc +pfs_atomic.cc +pfs_check.cc +pfs_column_values.cc +pfs_defaults.cc +pfs_engine_table.cc +pfs_events_waits.cc +pfs_global.cc +pfs_instr.cc +pfs_instr_class.cc +pfs_server.cc +pfs_setup_actor.cc +pfs_setup_object.cc +pfs_timer.cc +pfs_visitor.cc +table_all_instr.cc +table_events_waits.cc +table_events_waits_summary.cc +table_ews_by_thread_by_event_name.cc +table_ews_global_by_event_name.cc +table_file_instances.cc +table_file_summary.cc +table_helper.cc +table_os_global_by_type.cc +table_performance_timers.cc +table_setup_actors.cc +table_setup_consumers.cc +table_setup_instruments.cc +table_setup_objects.cc +table_setup_timers.cc +table_sync_instances.cc +table_threads.cc +table_tiws_by_index_usage.cc +table_tiws_by_table.cc +table_tlws_by_table.cc ) MYSQL_ADD_PLUGIN(perfschema ${PERFSCHEMA_SOURCES} STORAGE_ENGINE DEFAULT STATIC_ONLY) === added file 'storage/perfschema/pfs_visitor.cc' --- a/storage/perfschema/pfs_visitor.cc 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/pfs_visitor.cc 2011-01-07 16:20:19 +0000 @@ -0,0 +1,454 @@ +/* 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, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ + +#include "my_global.h" +#include "my_sys.h" +#include "pfs_visitor.h" +#include "pfs_instr.h" + +/** + @file storage/perfschema/pfs_visitor.cc + Visitors (implementation). +*/ + +/** + @addtogroup Performance_schema_buffers + @{ +*/ + +void PFS_connection_iterator::visit_global(bool with_threads, + PFS_connection_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_global(); + + 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()) + visitor->visit_thread(pfs); + } + } +} + +void PFS_instance_iterator::visit_mutex_instances(PFS_mutex_class *klass, + PFS_instance_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_mutex_class(klass); + + if (klass->is_singleton()) + { + PFS_mutex *pfs= sanitize_mutex(klass->m_singleton); + if (likely(pfs != NULL)) + { + if (likely(pfs->m_lock.is_populated())) + { + visitor->visit_mutex(pfs); + } + } + } + else + { + PFS_mutex *pfs= mutex_array; + PFS_mutex *pfs_last= pfs + mutex_max; + for ( ; pfs < pfs_last; pfs++) + { + if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) + { + visitor->visit_mutex(pfs); + } + } + } +} + +void PFS_instance_iterator::visit_rwlock_instances(PFS_rwlock_class *klass, + PFS_instance_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_rwlock_class(klass); + + if (klass->is_singleton()) + { + PFS_rwlock *pfs= sanitize_rwlock(klass->m_singleton); + if (likely(pfs != NULL)) + { + if (likely(pfs->m_lock.is_populated())) + { + visitor->visit_rwlock(pfs); + } + } + } + else + { + PFS_rwlock *pfs= rwlock_array; + PFS_rwlock *pfs_last= pfs + rwlock_max; + for ( ; pfs < pfs_last; pfs++) + { + if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) + { + visitor->visit_rwlock(pfs); + } + } + } +} + +void PFS_instance_iterator::visit_cond_instances(PFS_cond_class *klass, + PFS_instance_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_cond_class(klass); + + if (klass->is_singleton()) + { + PFS_cond *pfs= sanitize_cond(klass->m_singleton); + if (likely(pfs != NULL)) + { + if (likely(pfs->m_lock.is_populated())) + { + visitor->visit_cond(pfs); + } + } + } + else + { + PFS_cond *pfs= cond_array; + PFS_cond *pfs_last= pfs + cond_max; + for ( ; pfs < pfs_last; pfs++) + { + if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) + { + visitor->visit_cond(pfs); + } + } + } +} + +void PFS_instance_iterator::visit_file_instances(PFS_file_class *klass, + PFS_instance_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_file_class(klass); + + if (klass->is_singleton()) + { + PFS_file *pfs= sanitize_file(klass->m_singleton); + if (likely(pfs != NULL)) + { + if (likely(pfs->m_lock.is_populated())) + { + visitor->visit_file(pfs); + } + } + } + else + { + PFS_file *pfs= file_array; + PFS_file *pfs_last= pfs + file_max; + for ( ; pfs < pfs_last; pfs++) + { + if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) + { + visitor->visit_file(pfs); + } + } + } +} + +void PFS_object_iterator::visit_all_tables(PFS_object_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_global(); + + /* For all the table shares ... */ + PFS_table_share *share= table_share_array; + PFS_table_share *share_last= table_share_array + table_share_max; + for ( ; share < share_last; share++) + { + if (share->m_lock.is_populated()) + { + visitor->visit_table_share(share); + } + } + + /* For all the table handles ... */ + PFS_table *table= table_array; + PFS_table *table_last= table_array + table_max; + for ( ; table < table_last; table++) + { + if (table->m_lock.is_populated()) + { + visitor->visit_table(table); + } + } +} + +void PFS_object_iterator::visit_tables(PFS_table_share *share, + PFS_object_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_table_share(share); + + /* For all the table handles ... */ + PFS_table *table= table_array; + PFS_table *table_last= table_array + table_max; + for ( ; table < table_last; table++) + { + if ((table->m_share == share) && table->m_lock.is_populated()) + { + visitor->visit_table(table); + } + } +} + +void PFS_object_iterator::visit_table_indexes(PFS_table_share *share, + uint index, + PFS_object_visitor *visitor) +{ + DBUG_ASSERT(visitor != NULL); + + visitor->visit_table_share_index(share, index); + + /* For all the table handles ... */ + PFS_table *table= table_array; + PFS_table *table_last= table_array + table_max; + for ( ; table < table_last; table++) + { + if ((table->m_share == share) && table->m_lock.is_populated()) + { + visitor->visit_table_index(table, index); + } + } +} + +PFS_connection_wait_visitor +::PFS_connection_wait_visitor(PFS_instr_class *klass) +{ + m_index= klass->m_event_name_index; +} + +PFS_connection_wait_visitor::~PFS_connection_wait_visitor() +{} + +void PFS_connection_wait_visitor::visit_global() +{ + /* Sum by instances, not by connection */ + DBUG_ASSERT(false); +} + +void PFS_connection_wait_visitor::visit_thread(PFS_thread *pfs) +{ + m_stat.aggregate(& pfs->m_instr_class_wait_stats[m_index]); +} + +PFS_instance_wait_visitor::PFS_instance_wait_visitor() +{ +} + +PFS_instance_wait_visitor::~PFS_instance_wait_visitor() +{} + +void PFS_instance_wait_visitor::visit_mutex_class(PFS_mutex_class *pfs) +{ + uint index= pfs->m_event_name_index; + m_stat.aggregate(& global_instr_class_waits_array[index]); +} + +void PFS_instance_wait_visitor::visit_rwlock_class(PFS_rwlock_class *pfs) +{ + uint index= pfs->m_event_name_index; + m_stat.aggregate(& global_instr_class_waits_array[index]); +} + +void PFS_instance_wait_visitor::visit_cond_class(PFS_cond_class *pfs) +{ + uint index= pfs->m_event_name_index; + m_stat.aggregate(& global_instr_class_waits_array[index]); +} + +void PFS_instance_wait_visitor::visit_file_class(PFS_file_class *pfs) +{ + uint index= pfs->m_event_name_index; + m_stat.aggregate(& global_instr_class_waits_array[index]); +} + +void PFS_instance_wait_visitor::visit_mutex(PFS_mutex *pfs) +{ + m_stat.aggregate(& pfs->m_wait_stat); +} + +void PFS_instance_wait_visitor::visit_rwlock(PFS_rwlock *pfs) +{ + m_stat.aggregate(& pfs->m_wait_stat); +} + +void PFS_instance_wait_visitor::visit_cond(PFS_cond *pfs) +{ + m_stat.aggregate(& pfs->m_wait_stat); +} + +void PFS_instance_wait_visitor::visit_file(PFS_file *pfs) +{ + m_stat.aggregate(& pfs->m_wait_stat); +} + +PFS_table_io_wait_visitor::PFS_table_io_wait_visitor() +{} + +PFS_table_io_wait_visitor::~PFS_table_io_wait_visitor() +{} + +void PFS_table_io_wait_visitor::visit_global() +{ + uint index= global_table_io_class.m_event_name_index; + m_stat.aggregate(& global_instr_class_waits_array[index]); +} + +void PFS_table_io_wait_visitor::visit_table_share(PFS_table_share *pfs) +{ + PFS_table_io_stat io_stat; + uint index; + + /* Aggregate index stats */ + for (index= 0; index < pfs->m_key_count; index++) + io_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]); + + /* Aggregate global stats */ + io_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_KEY]); + + io_stat.sum(& m_stat); +} + +void PFS_table_io_wait_visitor::visit_table(PFS_table *pfs) +{ + PFS_table_share *safe_share= sanitize_table_share(pfs->m_share); + + if (likely(safe_share != NULL)) + { + PFS_table_io_stat io_stat; + uint index; + + /* Aggregate index stats */ + for (index= 0; index < safe_share->m_key_count; index++) + io_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]); + + /* Aggregate global stats */ + io_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_KEY]); + + io_stat.sum(& m_stat); + } +} + +PFS_table_io_stat_visitor::PFS_table_io_stat_visitor() +{} + +PFS_table_io_stat_visitor::~PFS_table_io_stat_visitor() +{} + +void PFS_table_io_stat_visitor::visit_table_share(PFS_table_share *pfs) +{ + uint index; + + /* Aggregate index stats */ + for (index= 0; index < pfs->m_key_count; index++) + m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]); + + /* Aggregate global stats */ + m_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_KEY]); +} + +void PFS_table_io_stat_visitor::visit_table(PFS_table *pfs) +{ + PFS_table_share *safe_share= sanitize_table_share(pfs->m_share); + + if (likely(safe_share != NULL)) + { + uint index; + + /* Aggregate index stats */ + for (index= 0; index < safe_share->m_key_count; index++) + m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]); + + /* Aggregate global stats */ + m_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_KEY]); + } +} + +PFS_index_io_stat_visitor::PFS_index_io_stat_visitor() +{} + +PFS_index_io_stat_visitor::~PFS_index_io_stat_visitor() +{} + +void PFS_index_io_stat_visitor::visit_table_share_index(PFS_table_share *pfs, uint index) +{ + m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]); +} + +void PFS_index_io_stat_visitor::visit_table_index(PFS_table *pfs, uint index) +{ + m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]); +} + +PFS_table_lock_wait_visitor::PFS_table_lock_wait_visitor() +{} + +PFS_table_lock_wait_visitor::~PFS_table_lock_wait_visitor() +{} + +void PFS_table_lock_wait_visitor::visit_global() +{ + uint index= global_table_lock_class.m_event_name_index; + m_stat.aggregate(& global_instr_class_waits_array[index]); +} + +void PFS_table_lock_wait_visitor::visit_table_share(PFS_table_share *pfs) +{ + pfs->m_table_stat.sum_lock(& m_stat); +} + +void PFS_table_lock_wait_visitor::visit_table(PFS_table *pfs) +{ + pfs->m_table_stat.sum_lock(& m_stat); +} + +PFS_table_lock_stat_visitor::PFS_table_lock_stat_visitor() +{} + +PFS_table_lock_stat_visitor::~PFS_table_lock_stat_visitor() +{} + +void PFS_table_lock_stat_visitor::visit_table_share(PFS_table_share *pfs) +{ + m_stat.aggregate(& pfs->m_table_stat.m_lock_stat); +} + +void PFS_table_lock_stat_visitor::visit_table(PFS_table *pfs) +{ + m_stat.aggregate(& pfs->m_table_stat.m_lock_stat); +} + +/** @} */ + === added file 'storage/perfschema/pfs_visitor.h' --- a/storage/perfschema/pfs_visitor.h 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/pfs_visitor.h 2011-01-07 16:20:19 +0000 @@ -0,0 +1,313 @@ +/* Copyright (c) 2010, 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 PFS_VISITOR_H +#define PFS_VISITOR_H + +#include "pfs_stat.h" + +/** + @file storage/perfschema/pfs_visitor.h + Visitors (declarations). +*/ + +/** + @addtogroup Performance_schema_buffers + @{ +*/ + +struct PFS_thread; +struct PFS_instr_class; +struct PFS_mutex_class; +struct PFS_rwlock_class; +struct PFS_cond_class; +struct PFS_file_class; +struct PFS_table_share; +struct PFS_mutex; +struct PFS_rwlock; +struct PFS_cond; +struct PFS_file; +struct PFS_table; +struct PFS_stage_class; +struct PFS_statement_class; + +/** + Interface class to visit groups of connections. + @sa PFS_connection_iterator +*/ +class PFS_connection_visitor +{ +public: + PFS_connection_visitor() {} + virtual ~PFS_connection_visitor() {} + /** Visit all connections. */ + virtual void visit_global() {} + /** Visit all a thread. */ + virtual void visit_thread(PFS_thread *pfs) {} +}; + +/** + Iterator over groups of connections. + @sa PFS_connection_visitor +*/ +class PFS_connection_iterator +{ +public: + /** + Visit all connections. + @param with_threads when true, visit also all threads. + @param visitor the visitor to call + */ + static void visit_global(bool with_threads, + PFS_connection_visitor *visitor); + /** + Visit a thread or connection. + @param thread the thread to visit. + @param visitor the visitor to call + */ + static inline void visit_thread(PFS_thread *thread, + PFS_connection_visitor *visitor) + { visitor->visit_thread(thread); } +}; + +/** + Interface class to visit groups of instrumentation point instances. + @sa PFS_instance_iterator +*/ +class PFS_instance_visitor +{ +public: + PFS_instance_visitor() {} + virtual ~PFS_instance_visitor() {} + /** Visit a mutex class. */ + virtual void visit_mutex_class(PFS_mutex_class *pfs) {} + /** Visit a rwlock class. */ + virtual void visit_rwlock_class(PFS_rwlock_class *pfs) {} + /** Visit a cond class. */ + virtual void visit_cond_class(PFS_cond_class *pfs) {} + /** Visit a file class. */ + virtual void visit_file_class(PFS_file_class *pfs) {} + /** Visit a mutex instance. */ + virtual void visit_mutex(PFS_mutex *pfs) {} + /** Visit a rwlock instance. */ + virtual void visit_rwlock(PFS_rwlock *pfs) {} + /** Visit a cond instance. */ + virtual void visit_cond(PFS_cond *pfs) {} + /** Visit a file instance. */ + virtual void visit_file(PFS_file *pfs) {} +}; + +/** + Iterator over groups of instrumentation point instances. + @sa PFS_instance_visitor +*/ +class PFS_instance_iterator +{ +public: + /** + Visit a mutex class and related instances. + @param klass the klass to visit. + @param visitor the visitor to call + */ + static void visit_mutex_instances(PFS_mutex_class *klass, + PFS_instance_visitor *visitor); + /** + Visit a rwlock class and related instances. + @param klass the klass to visit. + @param visitor the visitor to call + */ + static void visit_rwlock_instances(PFS_rwlock_class *klass, + PFS_instance_visitor *visitor); + /** + Visit a cond class and related instances. + @param klass the klass to visit. + @param visitor the visitor to call + */ + static void visit_cond_instances(PFS_cond_class *klass, + PFS_instance_visitor *visitor); + /** + Visit a file class and related instances. + @param klass the klass to visit. + @param visitor the visitor to call + */ + static void visit_file_instances(PFS_file_class *klass, + PFS_instance_visitor *visitor); +}; + +/** + Interface class to visit groups of SQL objects. + @sa PFS_object_iterator +*/ +class PFS_object_visitor +{ +public: + PFS_object_visitor() {} + virtual ~PFS_object_visitor() {} + /** Visit global data. */ + virtual void visit_global() {} + /** Visit a table share. */ + virtual void visit_table_share(PFS_table_share *pfs) {} + /** Visit a table share index. */ + virtual void visit_table_share_index(PFS_table_share *pfs, uint index) {} + /** Visit a table. */ + virtual void visit_table(PFS_table *pfs) {} + /** Visit a table index. */ + virtual void visit_table_index(PFS_table *pfs, uint index) {} +}; + +/** + Iterator over groups of SQL objects. + @sa PFS_object_visitor +*/ +class PFS_object_iterator +{ +public: + /** Visit all tables and related handles. */ + static void visit_all_tables(PFS_object_visitor *visitor); + /** Visit a table and related table handles. */ + static void visit_tables(PFS_table_share *share, + PFS_object_visitor *visitor); + /** Visit a table index and related table handles indexes. */ + static void visit_table_indexes(PFS_table_share *share, + uint index, + PFS_object_visitor *visitor); +}; + +/** + A concrete connection visitor that aggregates + wait statistics. +*/ +class PFS_connection_wait_visitor : public PFS_connection_visitor +{ +public: + /** Constructor. */ + PFS_connection_wait_visitor(PFS_instr_class *klass); + virtual ~PFS_connection_wait_visitor(); + virtual void visit_global(); + virtual void visit_thread(PFS_thread *pfs); + + /** EVENT_NAME instrument index. */ + uint m_index; + /** Wait statistic collected. */ + PFS_single_stat m_stat; +}; + +/** + A concrete instance visitor that aggregates + wait statistics. +*/ +class PFS_instance_wait_visitor : public PFS_instance_visitor +{ +public: + PFS_instance_wait_visitor(); + virtual ~PFS_instance_wait_visitor(); + virtual void visit_mutex_class(PFS_mutex_class *pfs); + virtual void visit_rwlock_class(PFS_rwlock_class *pfs); + virtual void visit_cond_class(PFS_cond_class *pfs); + virtual void visit_file_class(PFS_file_class *pfs); + virtual void visit_mutex(PFS_mutex *pfs); + virtual void visit_rwlock(PFS_rwlock *pfs); + virtual void visit_cond(PFS_cond *pfs); + virtual void visit_file(PFS_file *pfs); + + /** 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 +{ +public: + PFS_table_io_wait_visitor(); + virtual ~PFS_table_io_wait_visitor(); + virtual void visit_global(); + virtual void visit_table_share(PFS_table_share *pfs); + virtual void visit_table(PFS_table *pfs); + + /** Table io wait statistic collected. */ + PFS_single_stat m_stat; +}; + +/** + A concrete object visitor that aggregates + table io statistics. +*/ +class PFS_table_io_stat_visitor : public PFS_object_visitor +{ +public: + PFS_table_io_stat_visitor(); + virtual ~PFS_table_io_stat_visitor(); + virtual void visit_table_share(PFS_table_share *pfs); + virtual void visit_table(PFS_table *pfs); + + /** Table io statistic collected. */ + PFS_table_io_stat m_stat; +}; + +/** + A concrete object visitor that aggregates + index io statistics. +*/ +class PFS_index_io_stat_visitor : public PFS_object_visitor +{ +public: + PFS_index_io_stat_visitor(); + virtual ~PFS_index_io_stat_visitor(); + virtual void visit_table_share_index(PFS_table_share *pfs, uint index); + virtual void visit_table_index(PFS_table *pfs, uint index); + + /** Index io statistic collected. */ + PFS_table_io_stat m_stat; +}; + +/** + A concrete object visitor that aggregates + table lock wait statistics. +*/ +class PFS_table_lock_wait_visitor : public PFS_object_visitor +{ +public: + PFS_table_lock_wait_visitor(); + virtual ~PFS_table_lock_wait_visitor(); + virtual void visit_global(); + virtual void visit_table_share(PFS_table_share *pfs); + virtual void visit_table(PFS_table *pfs); + + /** Table lock wait statistic collected. */ + PFS_single_stat m_stat; +}; + +/** + A concrete object visitor that aggregates + table lock statistics. +*/ +class PFS_table_lock_stat_visitor : public PFS_object_visitor +{ +public: + PFS_table_lock_stat_visitor(); + virtual ~PFS_table_lock_stat_visitor(); + virtual void visit_table_share(PFS_table_share *pfs); + virtual void visit_table(PFS_table *pfs); + + /** Table lock statistic collected. */ + PFS_table_lock_stat m_stat; +}; + +/** @} */ +#endif + === modified file 'storage/perfschema/table_ews_by_thread_by_event_name.cc' --- a/storage/perfschema/table_ews_by_thread_by_event_name.cc 2010-11-15 09:58:20 +0000 +++ b/storage/perfschema/table_ews_by_thread_by_event_name.cc 2011-01-07 16:20:19 +0000 @@ -25,6 +25,7 @@ #include "pfs_column_values.h" #include "table_ews_by_thread_by_event_name.h" #include "pfs_global.h" +#include "pfs_visitor.h" THR_LOCK table_ews_by_thread_by_event_name::m_table_lock; @@ -302,26 +303,25 @@ void table_ews_by_thread_by_event_name ::make_row(PFS_thread *thread, PFS_instr_class *klass) { pfs_lock lock; - PFS_single_stat *event_name_array; - PFS_single_stat *stat; - uint index= klass->m_event_name_index; - event_name_array= thread->m_instr_class_wait_stats; - m_row_exists= false; /* Protect this reader against a thread termination */ thread->m_lock.begin_optimistic_lock(&lock); m_row.m_thread_internal_id= thread->m_thread_internal_id; - m_row.m_name= klass->m_name; - m_row.m_name_length= klass->m_name_length; - stat= & event_name_array[index]; - time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, stat); + m_row.m_event_name.make_row(klass); + + PFS_connection_wait_visitor visitor(klass); + PFS_connection_iterator::visit_thread(thread, & visitor); + + if (! thread->m_lock.end_optimistic_lock(&lock)) + return; + + m_row_exists= true; - if (thread->m_lock.end_optimistic_lock(&lock)) - 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_thread_by_event_name @@ -345,26 +345,12 @@ int table_ews_by_thread_by_event_name case 0: /* THREAD_ID */ set_field_ulong(f, m_row.m_thread_internal_id); break; - case 1: /* NAME */ - set_field_varchar_utf8(f, m_row.m_name, m_row.m_name_length); - break; - case 2: /* COUNT */ - set_field_ulonglong(f, m_row.m_stat.m_count); - break; - case 3: /* SUM */ - set_field_ulonglong(f, m_row.m_stat.m_sum); - break; - case 4: /* MIN */ - set_field_ulonglong(f, m_row.m_stat.m_min); - break; - case 5: /* AVG */ - set_field_ulonglong(f, m_row.m_stat.m_avg); + case 1: /* EVENT_NAME */ + m_row.m_event_name.set_field(f); break; - case 6: /* MAX */ - set_field_ulonglong(f, m_row.m_stat.m_max); + default: /* 2, ... COUNT/SUM/MIN/AVG/MAX */ + m_row.m_stat.set_field(f->field_index - 2, f); break; - default: - DBUG_ASSERT(false); } } } === modified file 'storage/perfschema/table_ews_by_thread_by_event_name.h' --- a/storage/perfschema/table_ews_by_thread_by_event_name.h 2010-09-23 16:08:54 +0000 +++ b/storage/perfschema/table_ews_by_thread_by_event_name.h 2011-01-07 16:20:19 +0000 @@ -41,9 +41,7 @@ struct row_ews_by_thread_by_event_name /** Column THREAD_ID. */ ulong m_thread_internal_id; /** Column EVENT_NAME. */ - const char *m_name; - /** Length in bytes of @c m_name. */ - uint m_name_length; + PFS_event_name_row m_event_name; /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */ PFS_stat_row m_stat; }; === modified file 'storage/perfschema/table_ews_global_by_event_name.cc' --- a/storage/perfschema/table_ews_global_by_event_name.cc 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_ews_global_by_event_name.cc 2011-01-07 16:20:19 +0000 @@ -27,6 +27,7 @@ #include "pfs_global.h" #include "pfs_instr.h" #include "pfs_timer.h" +#include "pfs_visitor.h" THR_LOCK table_ews_global_by_event_name::m_table_lock; @@ -245,270 +246,81 @@ table_ews_global_by_event_name::rnd_pos( return HA_ERR_RECORD_DELETED; } - void table_ews_global_by_event_name ::make_mutex_row(PFS_mutex_class *klass) { - m_row.m_name= klass->m_name; - m_row.m_name_length= klass->m_name_length; - uint index= klass->m_event_name_index; - PFS_single_stat cumulated_stat= global_instr_class_waits_array[index]; + m_row.m_event_name.make_row(klass); - if (klass->is_singleton()) - { - PFS_mutex *pfs= sanitize_mutex(klass->m_singleton); - if (likely(pfs != NULL)) - { - if (likely(pfs->m_lock.is_populated())) - { - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } - else - { - /* For all the mutex instances ... */ - PFS_mutex *pfs= mutex_array; - PFS_mutex *pfs_last= mutex_array + mutex_max; - for ( ; pfs < pfs_last; pfs++) - { - if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) - { - /* - If the instance belongs to this class, - aggregate the instance statistics. - */ - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } + PFS_instance_wait_visitor visitor; + PFS_instance_iterator::visit_mutex_instances(klass, & visitor); time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, & visitor.m_stat); m_row_exists= true; } void table_ews_global_by_event_name ::make_rwlock_row(PFS_rwlock_class *klass) { - m_row.m_name= klass->m_name; - m_row.m_name_length= klass->m_name_length; - uint index= klass->m_event_name_index; - PFS_single_stat cumulated_stat= global_instr_class_waits_array[index]; + m_row.m_event_name.make_row(klass); - if (klass->is_singleton()) - { - PFS_rwlock *pfs= sanitize_rwlock(klass->m_singleton); - if (likely(pfs != NULL)) - { - if (likely(pfs->m_lock.is_populated())) - { - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } - else - { - /* For all the rwlock instances ... */ - PFS_rwlock *pfs= rwlock_array; - PFS_rwlock *pfs_last= rwlock_array + rwlock_max; - for ( ; pfs < pfs_last; pfs++) - { - if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) - { - /* - If the instance belongs to this class, - aggregate the instance statistics. - */ - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } + PFS_instance_wait_visitor visitor; + PFS_instance_iterator::visit_rwlock_instances(klass, & visitor); time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, & visitor.m_stat); m_row_exists= true; } void table_ews_global_by_event_name ::make_cond_row(PFS_cond_class *klass) { - m_row.m_name= klass->m_name; - m_row.m_name_length= klass->m_name_length; - uint index= klass->m_event_name_index; - PFS_single_stat cumulated_stat= global_instr_class_waits_array[index]; + m_row.m_event_name.make_row(klass); - if (klass->is_singleton()) - { - PFS_cond *pfs= sanitize_cond(klass->m_singleton); - if (likely(pfs != NULL)) - { - if (likely(pfs->m_lock.is_populated())) - { - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } - else - { - /* For all the cond instances ... */ - PFS_cond *pfs= cond_array; - PFS_cond *pfs_last= cond_array + cond_max; - for ( ; pfs < pfs_last; pfs++) - { - if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) - { - /* - If the instance belongs to this class, - aggregate the instance statistics. - */ - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } + PFS_instance_wait_visitor visitor; + PFS_instance_iterator::visit_cond_instances(klass, & visitor); time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, & visitor.m_stat); m_row_exists= true; } void table_ews_global_by_event_name ::make_file_row(PFS_file_class *klass) { - m_row.m_name= klass->m_name; - m_row.m_name_length= klass->m_name_length; - uint index= klass->m_event_name_index; - PFS_single_stat cumulated_stat= global_instr_class_waits_array[index]; - - if (klass->is_singleton()) - { - PFS_file *pfs= sanitize_file(klass->m_singleton); - if (likely(pfs != NULL)) - { - if (likely(pfs->m_lock.is_populated())) - { - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } - else - { - /* For all the file instances ... */ - PFS_file *pfs= file_array; - PFS_file *pfs_last= file_array + file_max; - for ( ; pfs < pfs_last; pfs++) - { - if ((pfs->m_class == klass) && pfs->m_lock.is_populated()) - { - /* - If the instance belongs to this class, - aggregate the instance statistics. - */ - cumulated_stat.aggregate(& pfs->m_wait_stat); - } - } - } + m_row.m_event_name.make_row(klass); - /* FIXME: */ - /* For all the file handles ... */ + PFS_instance_wait_visitor visitor; + PFS_instance_iterator::visit_file_instances(klass, & visitor); time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, & visitor.m_stat); m_row_exists= true; } void table_ews_global_by_event_name ::make_table_io_row(PFS_instr_class *klass) { - m_row.m_name= klass->m_name; - m_row.m_name_length= klass->m_name_length; - uint index= klass->m_event_name_index; - PFS_single_stat cumulated_stat= global_instr_class_waits_array[index]; - PFS_table_io_stat cumulated_io_stat; - - /* For all the table shares ... */ - PFS_table_share *share= table_share_array; - PFS_table_share *share_last= table_share_array + table_share_max; - for ( ; share < share_last; share++) - { - if (share->m_lock.is_populated()) - { - /* Aggregate index stats */ - for (index= 0; index <= share->m_key_count; index++) - cumulated_io_stat.aggregate(& share->m_table_stat.m_index_stat[index]); - - /* Aggregate global stats */ - cumulated_io_stat.aggregate(& share->m_table_stat.m_index_stat[MAX_KEY]); - } - } - - /* For all the table handles ... */ - PFS_table *table= table_array; - PFS_table *table_last= table_array + table_max; - for ( ; table < table_last; table++) - { - if (table->m_lock.is_populated()) - { - PFS_table_share *safe_share= sanitize_table_share(table->m_share); - - if (likely(safe_share != NULL)) - { - /* Aggregate index stats */ - for (index= 0; index <= safe_share->m_key_count; index++) - cumulated_io_stat.aggregate(& table->m_table_stat.m_index_stat[index]); + m_row.m_event_name.make_row(klass); - /* Aggregate global stats */ - cumulated_io_stat.aggregate(& table->m_table_stat.m_index_stat[MAX_KEY]); - } - } - } - - cumulated_io_stat.sum(& cumulated_stat); + PFS_table_io_wait_visitor visitor; + PFS_object_iterator::visit_all_tables(& visitor); time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, & visitor.m_stat); m_row_exists= true; } void table_ews_global_by_event_name ::make_table_lock_row(PFS_instr_class *klass) { - m_row.m_name= klass->m_name; - m_row.m_name_length= klass->m_name_length; - uint index= klass->m_event_name_index; - PFS_single_stat cumulated_stat= global_instr_class_waits_array[index]; - - /* For all the table shares ... */ - PFS_table_share *share= table_share_array; - PFS_table_share *share_last= table_share_array + table_share_max; - for ( ; share < share_last; share++) - { - if (share->m_lock.is_populated()) - { - /* Aggregate lock stats */ - share->m_table_stat.sum_lock(& cumulated_stat); - } - } - - /* For all the table handles ... */ - PFS_table *table= table_array; - PFS_table *table_last= table_array + table_max; - for ( ; table < table_last; table++) - { - if (table->m_lock.is_populated()) - { - PFS_table_share *safe_share= sanitize_table_share(table->m_share); - - if (likely(safe_share != NULL)) - { - /* Aggregate lock stats */ - table->m_table_stat.sum_lock(& cumulated_stat); - } - } - } + m_row.m_event_name.make_row(klass); + PFS_table_lock_wait_visitor visitor; + PFS_object_iterator::visit_all_tables(& visitor); + time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, & visitor.m_stat); m_row_exists= true; } @@ -530,26 +342,12 @@ int table_ews_global_by_event_name { switch(f->field_index) { - case 0: /* NAME */ - set_field_varchar_utf8(f, m_row.m_name, m_row.m_name_length); - break; - case 1: /* COUNT */ - set_field_ulonglong(f, m_row.m_stat.m_count); - break; - case 2: /* SUM */ - set_field_ulonglong(f, m_row.m_stat.m_sum); - break; - case 3: /* MIN */ - set_field_ulonglong(f, m_row.m_stat.m_min); - break; - case 4: /* AVG */ - set_field_ulonglong(f, m_row.m_stat.m_avg); + case 0: /* EVENT_NAME */ + m_row.m_event_name.set_field(f); break; - case 5: /* MAX */ - set_field_ulonglong(f, m_row.m_stat.m_max); + default: /* 1, ... COUNT/SUM/MIN/AVG/MAX */ + m_row.m_stat.set_field(f->field_index - 1, f); break; - default: - DBUG_ASSERT(false); } } } === modified file 'storage/perfschema/table_ews_global_by_event_name.h' --- a/storage/perfschema/table_ews_global_by_event_name.h 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_ews_global_by_event_name.h 2011-01-07 16:20:19 +0000 @@ -39,9 +39,7 @@ struct row_ews_global_by_event_name { /** Column EVENT_NAME. */ - const char *m_name; - /** Length in bytes of @c m_name. */ - uint m_name_length; + PFS_event_name_row m_event_name; /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */ PFS_stat_row m_stat; }; === modified file 'storage/perfschema/table_helper.cc' --- a/storage/perfschema/table_helper.cc 2010-09-23 16:12:54 +0000 +++ b/storage/perfschema/table_helper.cc 2011-01-07 16:20:19 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 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 @@ -23,6 +23,82 @@ #include "pfs_engine_table.h" #include "table_helper.h" +int PFS_object_row::make_row(PFS_table_share *pfs) +{ + m_object_type= pfs->get_object_type(); + + m_schema_name_length= pfs->m_schema_name_length; + if (m_schema_name_length > sizeof(m_schema_name)) + return 1; + if (m_schema_name_length > 0) + memcpy(m_schema_name, pfs->m_schema_name, sizeof(m_schema_name)); + + m_object_name_length= pfs->m_table_name_length; + if (m_object_name_length > sizeof(m_object_name)) + return 1; + if (m_object_name_length > 0) + memcpy(m_object_name, pfs->m_table_name, sizeof(m_object_name)); + + return 0; +} + +void PFS_object_row::set_field(uint index, Field *f) +{ + switch(index) + { + case 0: /* OBJECT_TYPE */ + set_field_object_type(f, m_object_type); + break; + case 1: /* SCHEMA_NAME */ + PFS_engine_table::set_field_varchar_utf8(f, m_schema_name, m_schema_name_length); + break; + case 2: /* OBJECT_NAME */ + PFS_engine_table::set_field_varchar_utf8(f, m_object_name, m_object_name_length); + break; + default: + DBUG_ASSERT(false); + } +} + +int PFS_index_row::make_row(PFS_table_share *pfs, uint table_index) +{ + if (m_object_row.make_row(pfs)) + return 1; + + if (table_index < MAX_KEY) + { + PFS_table_key *key= &pfs->m_keys[table_index]; + m_index_name_length= key->m_name_length; + if (m_index_name_length > sizeof(m_index_name)) + return 1; + memcpy(m_index_name, key->m_name, sizeof(m_index_name)); + } + else + m_index_name_length= 0; + + return 0; +} + +void PFS_index_row::set_field(uint index, Field *f) +{ + switch(index) + { + case 0: /* OBJECT_TYPE */ + case 1: /* SCHEMA_NAME */ + case 2: /* OBJECT_NAME */ + m_object_row.set_field(index, f); + break; + case 3: /* INDEX_NAME */ + if (m_index_name_length > 0) + PFS_engine_table::set_field_varchar_utf8(f, m_index_name, m_index_name_length); + else + f->set_null(); + break; + default: + DBUG_ASSERT(false); + } +} + 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 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_helper.h 2011-01-07 16:20:19 +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 @@ -19,6 +19,8 @@ #include "pfs_column_types.h" #include "pfs_stat.h" #include "pfs_timer.h" +#include "pfs_engine_table.h" +#include "pfs_instr_class.h" /** @file storage/perfschema/table_helper.h @@ -53,6 +55,64 @@ struct PFS_object_view_constants static const uint VIEW_FUNCTION= 4; }; +/** Row fragment for column EVENT_NAME. */ +struct PFS_event_name_row +{ + /** Column EVENT_NAME. */ + const char *m_name; + /** Length in bytes of @c m_name. */ + uint m_name_length; + + /** Build a row from a memory buffer. */ + inline void make_row(PFS_instr_class *pfs) + { + m_name= pfs->m_name; + m_name_length= pfs->m_name_length; + } + + /** Set a table field from the row. */ + inline void set_field(Field *f) + { + PFS_engine_table::set_field_varchar_utf8(f, m_name, m_name_length); + } +}; + +/** Row fragment for columns OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME. */ +struct PFS_object_row +{ + /** Column OBJECT_TYPE. */ + enum_object_type m_object_type; + /** Column SCHEMA_NAME. */ + char m_schema_name[NAME_LEN]; + /** Length in bytes of @c m_schema_name. */ + uint m_schema_name_length; + /** Column OBJECT_NAME. */ + char m_object_name[NAME_LEN]; + /** Length in bytes of @c m_object_name. */ + uint m_object_name_length; + + /** Build a row from a memory buffer. */ + int make_row(PFS_table_share *pfs); + /** Set a table field from the row. */ + void set_field(uint index, Field *f); +}; + +/** Row fragment for columns OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME, INDEX_NAME. */ +struct PFS_index_row +{ + PFS_object_row m_object_row; + /** Column INDEX_NAME. */ + char m_index_name[NAME_LEN]; + /** Length in bytes of @c m_index_name. */ + uint m_index_name_length; + + /** Build a row from a memory buffer. */ + int make_row(PFS_table_share *pfs, uint table_index); + /** Set a table field from the row. */ + void set_field(uint index, Field *f); +}; + +/** Row fragment for single statistics columns (COUNT, SUM, MIN, AVG, MAX) */ struct PFS_stat_row { /** Column COUNT_STAR. */ @@ -66,6 +126,7 @@ struct PFS_stat_row /** Column MAX_TIMER_WAIT. */ ulonglong m_max; + /** Build a row from a memory buffer. */ inline void set(time_normalizer *normalizer, const PFS_single_stat *stat) { m_count= stat->m_count; @@ -75,7 +136,7 @@ struct PFS_stat_row m_sum= normalizer->wait_to_pico(stat->m_sum); m_min= normalizer->wait_to_pico(stat->m_min); m_max= normalizer->wait_to_pico(stat->m_max); - m_avg= normalizer->wait_to_pico(stat->m_sum / stat->m_count); + m_avg= normalizer->wait_to_pico(stat->m_sum / m_count); } else { @@ -85,8 +146,34 @@ struct PFS_stat_row m_max= 0; } } + + /** Set a table field from the row. */ + void set_field(uint index, Field *f) + { + switch (index) + { + case 0: /* COUNT */ + PFS_engine_table::set_field_ulonglong(f, m_count); + break; + case 1: /* SUM */ + PFS_engine_table::set_field_ulonglong(f, m_sum); + break; + case 2: /* MIN */ + PFS_engine_table::set_field_ulonglong(f, m_min); + break; + case 3: /* AVG */ + PFS_engine_table::set_field_ulonglong(f, m_avg); + break; + case 4: /* MAX */ + PFS_engine_table::set_field_ulonglong(f, m_max); + break; + default: + DBUG_ASSERT(false); + } + } }; +/** Row fragment for table io statistics columns. */ struct PFS_table_io_stat_row { PFS_stat_row m_all; @@ -97,6 +184,7 @@ struct PFS_table_io_stat_row PFS_stat_row m_update; PFS_stat_row m_delete; + /** Build a row from a memory buffer. */ inline void set(time_normalizer *normalizer, const PFS_table_io_stat *stat) { PFS_single_stat all_read; @@ -124,6 +212,7 @@ struct PFS_table_io_stat_row } }; +/** Row fragment for table lock statistics columns. */ struct PFS_table_lock_stat_row { PFS_stat_row m_all; @@ -141,6 +230,7 @@ struct PFS_table_lock_stat_row PFS_stat_row m_write_normal; PFS_stat_row m_write_external; + /** Build a row from a memory buffer. */ inline void set(time_normalizer *normalizer, const PFS_table_lock_stat *stat) { PFS_single_stat all_read; === modified file 'storage/perfschema/table_tiws_by_index_usage.cc' --- a/storage/perfschema/table_tiws_by_index_usage.cc 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_tiws_by_index_usage.cc 2011-01-07 16:20:19 +0000 @@ -25,6 +25,7 @@ #include "pfs_column_values.h" #include "table_tiws_by_index_usage.h" #include "pfs_global.h" +#include "pfs_visitor.h" THR_LOCK table_tiws_by_index_usage::m_table_lock; @@ -330,53 +331,24 @@ table_tiws_by_index_usage::rnd_pos(const void table_tiws_by_index_usage::make_row(PFS_table_share *share, uint index) { pfs_lock lock; - PFS_table_io_stat cumulated_stat; m_row_exists= false; share->m_lock.begin_optimistic_lock(&lock); - m_row.m_object_type= share->get_object_type(); - memcpy(m_row.m_schema_name, share->m_schema_name, share->m_schema_name_length); - m_row.m_schema_name_length= share->m_schema_name_length; - memcpy(m_row.m_object_name, share->m_table_name, share->m_table_name_length); - m_row.m_object_name_length= share->m_table_name_length; - if (index < MAX_KEY) - { - PFS_table_key *key= &share->m_keys[index]; - memcpy(m_row.m_index_name, key->m_name, key->m_name_length); - m_row.m_index_name_length= key->m_name_length; - } - else - m_row.m_index_name_length= 0; + if (m_row.m_index.make_row(share, index)) + return; - cumulated_stat= share->m_table_stat.m_index_stat[index]; + PFS_index_io_stat_visitor visitor; + PFS_object_iterator::visit_table_indexes(share, index, & visitor); if (! share->m_lock.end_optimistic_lock(&lock)) return; m_row_exists= true; - if (share->get_refcount() > 1) - { - /* For all the table handles still opened ... */ - PFS_table *table= table_array; - PFS_table *table_last= table_array + table_max; - for ( ; table < table_last ; table++) - { - if ((table->m_share == share) && (table->m_lock.is_populated())) - { - /* - If the opened table handle is for this table share, - aggregate the table handle statistics. - */ - cumulated_stat.aggregate(&table->m_table_stat.m_index_stat[index]); - } - } - } - time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, & visitor.m_stat); } int table_tiws_by_index_usage::read_row_values(TABLE *table, @@ -400,22 +372,10 @@ int table_tiws_by_index_usage::read_row_ switch(f->field_index) { case 0: /* OBJECT_TYPE */ - set_field_object_type(f, m_row.m_object_type); - break; case 1: /* SCHEMA_NAME */ - set_field_varchar_utf8(f, m_row.m_schema_name, - m_row.m_schema_name_length); - break; case 2: /* OBJECT_NAME */ - set_field_varchar_utf8(f, m_row.m_object_name, - m_row.m_object_name_length); - break; case 3: /* INDEX_NAME */ - if (m_row.m_index_name_length > 0) - set_field_varchar_utf8(f, m_row.m_index_name, - m_row.m_index_name_length); - else - f->set_null(); + m_row.m_index.set_field(f->field_index, f); break; case 4: /* COUNT_STAR */ set_field_ulonglong(f, m_row.m_stat.m_all.m_count); === modified file 'storage/perfschema/table_tiws_by_index_usage.h' --- a/storage/perfschema/table_tiws_by_index_usage.h 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_tiws_by_index_usage.h 2011-01-07 16:20:19 +0000 @@ -38,20 +38,8 @@ */ struct row_tiws_by_index_usage { - /** Column OBJECT_TYPE. */ - enum_object_type m_object_type; - /** Column SCHEMA_NAME. */ - char m_schema_name[NAME_LEN]; - /** Length in bytes of @c m_schema_name. */ - uint m_schema_name_length; - /** Column OBJECT_NAME. */ - char m_object_name[NAME_LEN]; - /** Length in bytes of @c m_object_name. */ - uint m_object_name_length; - /** Column INDEX_NAME. */ - char m_index_name[NAME_LEN]; - /** Length in bytes of @c m_index_name. */ - uint m_index_name_length; + /** Column OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME, INDEX_NAME. */ + PFS_index_row m_index; /** Columns COUNT/SUM/MIN/AVG/MAX (+_READ, +WRITE). */ PFS_table_io_stat_row m_stat; }; === modified file 'storage/perfschema/table_tiws_by_table.cc' --- a/storage/perfschema/table_tiws_by_table.cc 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_tiws_by_table.cc 2011-01-07 16:20:19 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 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 @@ -25,6 +25,7 @@ #include "pfs_column_values.h" #include "table_tiws_by_table.h" #include "pfs_global.h" +#include "pfs_visitor.h" THR_LOCK table_tiws_by_table::m_table_lock; @@ -307,57 +308,24 @@ table_tiws_by_table::rnd_pos(const void void table_tiws_by_table::make_row(PFS_table_share *share) { pfs_lock lock; - PFS_table_io_stat cumulated_stat; - uint index; m_row_exists= false; share->m_lock.begin_optimistic_lock(&lock); - m_row.m_object_type= share->get_object_type(); - memcpy(m_row.m_schema_name, share->m_schema_name, share->m_schema_name_length); - m_row.m_schema_name_length= share->m_schema_name_length; - memcpy(m_row.m_object_name, share->m_table_name, share->m_table_name_length); - m_row.m_object_name_length= share->m_table_name_length; - - /* Aggregate index stats */ - for (index= 0; index <= share->m_key_count; index++) - cumulated_stat.aggregate(& share->m_table_stat.m_index_stat[index]); + if (m_row.m_object.make_row(share)) + return; - /** Aggregate global stats */ - cumulated_stat.aggregate(& share->m_table_stat.m_index_stat[MAX_KEY]); + PFS_table_io_stat_visitor visitor; + PFS_object_iterator::visit_tables(share, & visitor); if (! share->m_lock.end_optimistic_lock(&lock)) return; m_row_exists= true; - if (share->get_refcount() > 1) - { - /* For all the table handles still opened ... */ - PFS_table *table= table_array; - PFS_table *table_last= table_array + table_max; - for ( ; table < table_last ; table++) - { - if ((table->m_share == share) && (table->m_lock.is_populated())) - { - /* - If the opened table handle is for this table share, - aggregate the table handle statistics. - */ - - /* Aggregate index stats */ - for (index= 0; index <= share->m_key_count; index++) - cumulated_stat.aggregate(& table->m_table_stat.m_index_stat[index]); - - /** Aggregate global stats */ - cumulated_stat.aggregate(& table->m_table_stat.m_index_stat[MAX_KEY]); - } - } - } - time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, &visitor.m_stat); } int table_tiws_by_table::read_row_values(TABLE *table, @@ -381,15 +349,9 @@ int table_tiws_by_table::read_row_values switch(f->field_index) { case 0: /* OBJECT_TYPE */ - set_field_object_type(f, m_row.m_object_type); - break; case 1: /* SCHEMA_NAME */ - set_field_varchar_utf8(f, m_row.m_schema_name, - m_row.m_schema_name_length); - break; case 2: /* OBJECT_NAME */ - set_field_varchar_utf8(f, m_row.m_object_name, - m_row.m_object_name_length); + m_row.m_object.set_field(f->field_index, f); break; case 3: /* COUNT_STAR */ set_field_ulonglong(f, m_row.m_stat.m_all.m_count); === modified file 'storage/perfschema/table_tiws_by_table.h' --- a/storage/perfschema/table_tiws_by_table.h 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_tiws_by_table.h 2011-01-07 16:20:19 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 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 @@ -38,16 +38,8 @@ */ struct row_tiws_by_table { - /** Column OBJECT_TYPE. */ - enum_object_type m_object_type; - /** Column SCHEMA_NAME. */ - char m_schema_name[NAME_LEN]; - /** Length in bytes of @c m_schema_name. */ - uint m_schema_name_length; - /** Column OBJECT_NAME. */ - char m_object_name[NAME_LEN]; - /** Length in bytes of @c m_object_name. */ - uint m_object_name_length; + /** Column OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME. */ + PFS_object_row m_object; /** Columns COUNT/SUM/MIN/AVG/MAX (+_READ, +WRITE). */ PFS_table_io_stat_row m_stat; }; === modified file 'storage/perfschema/table_tlws_by_table.cc' --- a/storage/perfschema/table_tlws_by_table.cc 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_tlws_by_table.cc 2011-01-07 16:20:19 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 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 @@ -25,6 +25,7 @@ #include "pfs_column_values.h" #include "table_tlws_by_table.h" #include "pfs_global.h" +#include "pfs_visitor.h" THR_LOCK table_tlws_by_table::m_table_lock; @@ -482,48 +483,24 @@ table_tlws_by_table::rnd_pos(const void void table_tlws_by_table::make_row(PFS_table_share *share) { pfs_lock lock; - PFS_table_lock_stat cumulated_stat; m_row_exists= false; share->m_lock.begin_optimistic_lock(&lock); - m_row.m_object_type= share->get_object_type(); - memcpy(m_row.m_schema_name, share->m_schema_name, share->m_schema_name_length); - m_row.m_schema_name_length= share->m_schema_name_length; - memcpy(m_row.m_object_name, share->m_table_name, share->m_table_name_length); - m_row.m_object_name_length= share->m_table_name_length; + if (m_row.m_object.make_row(share)) + return; - /** Aggregate global stats */ - cumulated_stat.aggregate(& share->m_table_stat.m_lock_stat); + PFS_table_lock_stat_visitor visitor; + PFS_object_iterator::visit_tables(share, & visitor); if (! share->m_lock.end_optimistic_lock(&lock)) return; m_row_exists= true; - if (share->get_refcount() > 1) - { - /* For all the table handles still opened ... */ - PFS_table *table= table_array; - PFS_table *table_last= table_array + table_max; - for ( ; table < table_last ; table++) - { - if ((table->m_share == share) && (table->m_lock.is_populated())) - { - /* - If the opened table handle is for this table share, - aggregate the table handle statistics. - */ - - /** Aggregate global stats */ - cumulated_stat.aggregate(& table->m_table_stat.m_lock_stat); - } - } - } - time_normalizer *normalizer= time_normalizer::get(wait_timer); - m_row.m_stat.set(normalizer, &cumulated_stat); + m_row.m_stat.set(normalizer, &visitor.m_stat); } int table_tlws_by_table::read_row_values(TABLE *table, @@ -547,15 +524,9 @@ int table_tlws_by_table::read_row_values switch(f->field_index) { case 0: /* OBJECT_TYPE */ - set_field_object_type(f, m_row.m_object_type); - break; case 1: /* SCHEMA_NAME */ - set_field_varchar_utf8(f, m_row.m_schema_name, - m_row.m_schema_name_length); - break; case 2: /* OBJECT_NAME */ - set_field_varchar_utf8(f, m_row.m_object_name, - m_row.m_object_name_length); + m_row.m_object.set_field(f->field_index, f); break; case 3: /* COUNT_STAR */ set_field_ulonglong(f, m_row.m_stat.m_all.m_count); === modified file 'storage/perfschema/table_tlws_by_table.h' --- a/storage/perfschema/table_tlws_by_table.h 2010-12-09 16:17:13 +0000 +++ b/storage/perfschema/table_tlws_by_table.h 2011-01-07 16:20:19 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 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 @@ -38,16 +38,8 @@ */ struct row_tlws_by_table { - /** Column OBJECT_TYPE. */ - enum_object_type m_object_type; - /** Column SCHEMA_NAME. */ - char m_schema_name[NAME_LEN]; - /** Length in bytes of @c m_schema_name. */ - uint m_schema_name_length; - /** Column OBJECT_NAME. */ - char m_object_name[NAME_LEN]; - /** Length in bytes of @c m_object_name. */ - uint m_object_name_length; + /** Column OBJECT_TYPE, SCHEMA_NAME, OBJECT_NAME. */ + PFS_object_row m_object; /** Columns COUNT/SUM/MIN/AVG/MAX READ/WRITE/READ_NORMAL/etc. */ PFS_table_lock_stat_row m_stat; }; No bundle (reason: useless for push emails).