From: Mayank Prasad Date: May 10 2011 6:26pm Subject: bzr commit into mysql-trunk-wl5767 branch (mayank.prasad:3367) WL#5767 List-Archive: http://lists.mysql.com/commits/137022 Message-Id: <201105101827.p4AIR8en003991@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0496711808==" --===============0496711808== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/mayank/mysql-tree/mysql-trunk-wl5767/ based on revid:marc.alff@stripped 3367 Mayank Prasad 2011-05-10 WL#5767 : First commit with skeleton code Changes Description: -------------------- Following coding is done as per LLD: 1) - Add new columns to events_statements_current / history / history_long tables. - Expose them as NULL. >> Coded. 2) - Create a new table events_statements_summary_by_digest - C++ file for this table: - storage/perfschema/table_esms_by_digest.h, .cc >> Coded. 3) - Add a new perfschema startup option: - performance-schema-digests-size >> Coded. 4) - Define new structures for internal buffers for events_statements_summary_by_digest - C++ files - storage/perfschema/pfs_digest.h, .cc - PFS_statement_digest_stat structure - statement_digest_stat_array[] >> Skeleton Coded. 5) - Change the performance schema initialization to allocate memory - for buffers in 4), using the size from 3) >> Skeleton Coded. added: storage/perfschema/pfs_digest.cc storage/perfschema/pfs_digest.h storage/perfschema/table_esms_by_digest.cc storage/perfschema/table_esms_by_digest.h modified: scripts/mysql_system_tables.sql sql/sys_vars.cc storage/perfschema/CMakeLists.txt storage/perfschema/pfs_column_types.h storage/perfschema/pfs_engine_table.cc storage/perfschema/pfs_server.cc storage/perfschema/pfs_server.h storage/perfschema/table_events_statements.cc storage/perfschema/table_events_statements.h === 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-10 18:26:49 +0000 @@ -873,7 +873,8 @@ SET @cmd="CREATE TABLE performance_schem "NO_INDEX_USED BIGINT unsigned not null," "NO_GOOD_INDEX_USED BIGINT unsigned not null," "NESTING_EVENT_ID BIGINT unsigned," - "NESTING_EVENT_TYPE ENUM('STATEMENT', 'STAGE', 'WAIT')" + "NESTING_EVENT_TYPE ENUM('STATEMENT', 'STAGE', 'WAIT')," + "DIGEST VARCHAR(64) not null" ")ENGINE=PERFORMANCE_SCHEMA;"; SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0'); @@ -922,7 +923,8 @@ SET @cmd="CREATE TABLE performance_schem "NO_INDEX_USED BIGINT unsigned not null," "NO_GOOD_INDEX_USED BIGINT unsigned not null," "NESTING_EVENT_ID BIGINT unsigned," - "NESTING_EVENT_TYPE ENUM('STATEMENT', 'STAGE', 'WAIT')" + "NESTING_EVENT_TYPE ENUM('STATEMENT', 'STAGE', 'WAIT')," + "DIGEST VARCHAR(64) not null" ")ENGINE=PERFORMANCE_SCHEMA;"; SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0'); @@ -971,7 +973,8 @@ SET @cmd="CREATE TABLE performance_schem "NO_INDEX_USED BIGINT unsigned not null," "NO_GOOD_INDEX_USED BIGINT unsigned not null," "NESTING_EVENT_ID BIGINT unsigned," - "NESTING_EVENT_TYPE ENUM('STATEMENT', 'STAGE', 'WAIT')" + "NESTING_EVENT_TYPE ENUM('STATEMENT', 'STAGE', 'WAIT')," + "DIGEST VARCHAR(64) not null" ")ENGINE=PERFORMANCE_SCHEMA;"; SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0'); @@ -1054,6 +1057,21 @@ PREPARE stmt FROM @str; EXECUTE stmt; DROP PREPARE stmt; +-- +-- TABLE EVENTS_STATEMENTS_SUMMARY_BY_DIGEST +-- + +SET @cmd="CREATE TABLE performance_schema.events_statements_summary_by_digest(" + "DIGEST VARCHAR(64) not null," + "COUNT_STAR 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; + 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-10 18:26:49 +0000 @@ -272,6 +272,14 @@ static Sys_var_ulong Sys_pfs_events_stat DEFAULT(PFS_STATEMENTS_HISTORY_SIZE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES); +static Sys_var_ulong Sys_pfs_digest_size( + "performance_schema_digests_size", + "TBD.", + READ_ONLY GLOBAL_VAR(pfs_param.m_digest_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 200), + DEFAULT(PFS_DIGEST_SIZE), + BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES); + #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ static Sys_var_ulong Sys_auto_increment_increment( === 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-10 18:26:49 +0000 @@ -32,6 +32,7 @@ pfs_column_types.h pfs_column_values.h pfs_con_slice.h pfs_defaults.h +pfs_digest.h pfs_engine_table.h pfs_events.h pfs_events_stages.h @@ -50,6 +51,7 @@ pfs_visitor.h table_all_instr.h table_esgs_by_thread_by_event_name.h table_esgs_global_by_event_name.h +table_esms_by_digest.h table_esms_by_thread_by_event_name.h table_esms_global_by_event_name.h table_events_stages.h @@ -80,6 +82,7 @@ pfs_check.cc pfs_column_values.cc pfs_con_slice.cc pfs_defaults.cc +pfs_digest.cc pfs_engine_table.cc pfs_events_stages.cc pfs_events_statements.cc @@ -95,6 +98,7 @@ pfs_visitor.cc table_all_instr.cc table_esgs_by_thread_by_event_name.cc table_esgs_global_by_event_name.cc +table_esms_by_digest.cc table_esms_by_thread_by_event_name.cc table_esms_global_by_event_name.cc table_events_stages.cc === modified file 'storage/perfschema/pfs_column_types.h' --- a/storage/perfschema/pfs_column_types.h 2011-04-04 14:34:42 +0000 +++ b/storage/perfschema/pfs_column_types.h 2011-05-10 18:26:49 +0000 @@ -53,6 +53,9 @@ /** Size of the SOURCE columns. */ #define COL_SOURCE_SIZE 64 +/** Size of the Digest columns. */ +#define COL_DIGEST_SIZE 64 + /** Enum values for the TIMER_NAME columns. This enum is found in the following tables: === added file 'storage/perfschema/pfs_digest.cc' --- a/storage/perfschema/pfs_digest.cc 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/pfs_digest.cc 2011-05-10 18:26:49 +0000 @@ -0,0 +1,51 @@ +/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + 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 */ + +/** + @file storage/perfschema/pfs_digest.h + Statement Digest data structures (implementation). +*/ + +#include "pfs_digest.h" + +/** EVENTS_STATEMENTS_HISTORY_LONG circular buffer. */ +PFS_statements_digest_stat *statements_digest_stat_array= NULL; + + +/** + Initialize table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. + @param digest_sizing +*/ +int init_digest(unsigned int digest_sizing) +{ + printf("\n Initializing performance_schema_digests with\ + digest_sizing=%d\n",digest_sizing); + + /* + TBD. Allocate memory for statements_digest_stat_array based on + performance_schema_digests_size values + */ + return 0; +} + +/** Cleanup table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. */ +int cleanup_digest(void) +{ + printf("\n Yes, cleaning up performance_schema_digests\n"); + /* + TBD. Free memory allocated to statements_digest_stat_array. + */ + return 0; +} === added file 'storage/perfschema/pfs_digest.h' --- a/storage/perfschema/pfs_digest.h 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/pfs_digest.h 2011-05-10 18:26:49 +0000 @@ -0,0 +1,35 @@ +/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + 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_DIGEST_H +#define PFS_DIGEST_H + +/** + @file storage/perfschema/pfs_digest.h + Statement Digest data structures (declarations). +*/ + +#include + +/** A statement stat record based on digest. */ +struct PFS_statements_digest_stat +{ + /* TBD */ +}; + +int init_digest(unsigned int digest_sizing); +int cleanup_digest(); + +#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-10 18:26:49 +0000 @@ -46,6 +46,7 @@ #include "table_events_statements.h" #include "table_esms_by_thread_by_event_name.h" #include "table_esms_global_by_event_name.h" +#include "table_esms_by_digest.h" /* For show status */ #include "pfs_column_values.h" @@ -99,6 +100,7 @@ static PFS_engine_table_share *all_share &table_events_statements_history_long::m_share, &table_esms_by_thread_by_event_name::m_share, &table_esms_global_by_event_name::m_share, + &table_esms_by_digest::m_share, NULL }; === 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-10 18:26:49 +0000 @@ -33,6 +33,7 @@ #include "pfs_setup_actor.h" #include "pfs_setup_object.h" #include "pfs_defaults.h" +#include "pfs_digest.h" PFS_global_param pfs_param; @@ -85,7 +86,8 @@ 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_digest(param->m_digest_sizing)) { /* The performance schema initialization failed. @@ -137,6 +139,7 @@ static void cleanup_performance_schema(v cleanup_setup_actor_hash(); cleanup_setup_object(); cleanup_setup_object_hash(); + cleanup_digest(); PFS_atomic::cleanup(); } === 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-10 18:26:49 +0000 @@ -90,6 +90,9 @@ #ifndef PFS_STATEMENTS_STACK_SIZE #define PFS_STATEMENTS_STACK_SIZE 10 #endif +#ifndef PFS_DIGEST_SIZE + #define PFS_DIGEST_SIZE 100 +#endif /** Performance schema global sizing parameters. */ struct PFS_global_param @@ -187,6 +190,8 @@ struct PFS_global_param ulong m_events_statements_history_sizing; /** Maximum number of rows in table EVENTS_STATEMENTS_HISTORY_LONG. */ ulong m_events_statements_history_long_sizing; + /** Maximum number of digests to be captured */ + ulong m_digest_sizing; }; /** === added file 'storage/perfschema/table_esms_by_digest.cc' --- a/storage/perfschema/table_esms_by_digest.cc 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/table_esms_by_digest.cc 2011-05-10 18:26:49 +0000 @@ -0,0 +1,167 @@ +/* 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_digest.cc + Table EVENTS_STATEMENTS_SUMMARY_GLOBAL_BY_DIGEST (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_digest.h" +#include "pfs_global.h" +#include "pfs_instr.h" +#include "pfs_timer.h" +#include "pfs_visitor.h" +#include "table_esms_by_digest.h" + +THR_LOCK table_esms_by_digest::m_table_lock; + +static const TABLE_FIELD_TYPE field_types[]= +{ + /* TBD */ + { + { C_STRING_WITH_LEN("DIGEST") }, + { C_STRING_WITH_LEN("varchar(64)") }, + { NULL, 0} + }, + { + { C_STRING_WITH_LEN("COUNT_STAR") }, + { C_STRING_WITH_LEN("bigint(20)") }, + { NULL, 0} + }, +}; + +TABLE_FIELD_DEF +table_esms_by_digest::m_field_def= +{ 2, field_types }; + +PFS_engine_table_share +table_esms_by_digest::m_share= +{ + { C_STRING_WITH_LEN("events_statements_summary_by_digest") }, + &pfs_truncatable_acl, + table_esms_by_digest::create, + NULL, /* write_row */ + table_esms_by_digest::delete_all_rows, + NULL, /* get_row_count */ + 1000, /* records */ + sizeof(PFS_simple_index), + &m_table_lock, + &m_field_def, + false /* checked */ +}; + +PFS_engine_table* +table_esms_by_digest::create(void) +{ + return new table_esms_by_digest(); +} + +int +table_esms_by_digest::delete_all_rows(void) +{ + /* TBD */ + return 0; +} + +table_esms_by_digest::table_esms_by_digest() + : PFS_engine_table(&m_share, &m_pos), + m_row_exists(false), m_pos(1), m_next_pos(1) +{} + +void table_esms_by_digest::reset_position(void) +{ + m_pos= 1; + m_next_pos= 1; +} + +int table_esms_by_digest::rnd_next(void) +{ + PFS_stage_class *stage_class; + + if (global_instr_class_stages_array == NULL) + return HA_ERR_END_OF_FILE; + + m_pos.set_at(&m_next_pos); + + stage_class= find_stage_class(m_pos.m_index); + if (stage_class) + { + make_row(/*TBD*/); + m_next_pos.set_after(&m_pos); + return 0; + } + + return HA_ERR_END_OF_FILE; +} + +int +table_esms_by_digest::rnd_pos(const void *pos) +{ + PFS_stage_class *stage_class; + + set_position(pos); + + if (global_instr_class_stages_array == NULL) + return HA_ERR_END_OF_FILE; + + stage_class=find_stage_class(m_pos.m_index); + if (stage_class) + { + make_row(/*TBD*/); + return 0; + } + + return HA_ERR_RECORD_DELETED; +} + + +void table_esms_by_digest::make_row(/*TBD*/) +{ + /* TBD */ + m_row_exists= true; +} + +int table_esms_by_digest +::read_row_values(TABLE *table, unsigned char *, 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 == 0); + + for (; (f= *fields) ; fields++) + { + if (read_all || bitmap_is_set(table->read_set, f->field_index)) + { + switch(f->field_index) + { + default: /* TBD */ + break; + } + } + } + + return 0; +} + === added file 'storage/perfschema/table_esms_by_digest.h' --- a/storage/perfschema/table_esms_by_digest.h 1970-01-01 00:00:00 +0000 +++ b/storage/perfschema/table_esms_by_digest.h 2011-05-10 18:26:49 +0000 @@ -0,0 +1,91 @@ +/* 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_DIGEST_H +#define TABLE_ESMS_BY_DIGEST_H + +/** + @file storage/perfschema/table_esms_by_digest.h + Table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST (declarations). +*/ + +#include "table_helper.h" + +/** + @addtogroup Performance_schema_tables + @{ +*/ + +/** + A row of table + PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. +*/ +struct row_esms_by_digest +{ + /** Columns TBD. Adding few dummy as of now. */ + + /** Column DIGEST. */ + char m_digest[COL_DIGEST_SIZE]; + + /** Columns COUNT_STAR, SUM/MIN/AVG/MAX TIMER_WAIT. */ + PFS_statement_stat_row m_stat; +}; + +/** Table PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. */ +class table_esms_by_digest : 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_digest(); + +public: + ~table_esms_by_digest() + {} + +protected: + void make_row(/*TBD*/); + +private: + /** Table share lock. */ + static THR_LOCK m_table_lock; + /** Fields definition. */ + static TABLE_FIELD_DEF m_field_def; + + /** Current row. */ + row_esms_by_digest m_row; + /** True is the current row exists. */ + bool m_row_exists; + /** Current position. */ + PFS_simple_index m_pos; + /** Next position. */ + PFS_simple_index m_next_pos; +}; + +/** @} */ +#endif === modified file 'storage/perfschema/table_events_statements.cc' --- a/storage/perfschema/table_events_statements.cc 2011-02-14 14:23:55 +0000 +++ b/storage/perfschema/table_events_statements.cc 2011-05-10 18:26:49 +0000 @@ -216,12 +216,17 @@ static const TABLE_FIELD_TYPE field_type { C_STRING_WITH_LEN("NESTING_EVENT_TYPE") }, { C_STRING_WITH_LEN("enum(\'STATEMENT\',\'STAGE\',\'WAIT\'") }, { NULL, 0} + }, + { + { C_STRING_WITH_LEN("DIGEST") }, + { C_STRING_WITH_LEN("varchar(64)") }, + { NULL, 0} } }; TABLE_FIELD_DEF table_events_statements_current::m_field_def= -{37 , field_types }; +{38 , field_types }; PFS_engine_table_share table_events_statements_current::m_share= @@ -351,6 +356,9 @@ void table_events_statements_common::mak m_row.m_no_index_used= statement->m_no_index_used; m_row.m_no_good_index_used= statement->m_no_good_index_used; + /* TBD. Following */ + strcpy(m_row.m_digest, "Mayank"); + m_row_exists= true; return; } @@ -519,6 +527,9 @@ int table_events_statements_common::read else f->set_null(); break; + case 37: /* DIGEST */ + /* TBD */ + break; default: DBUG_ASSERT(false); } === modified file 'storage/perfschema/table_events_statements.h' --- a/storage/perfschema/table_events_statements.h 2011-02-14 14:23:55 +0000 +++ b/storage/perfschema/table_events_statements.h 2011-05-10 18:26:49 +0000 @@ -110,6 +110,8 @@ struct row_events_statements ulonglong m_no_index_used; /** Column NO_GOOD_INDEX_USED. */ ulonglong m_no_good_index_used; + /** Column DIGEST. */ + char m_digest[COL_DIGEST_SIZE]; }; /** Position of a cursor on PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_CURRENT. */ --===============0496711808== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/mayank.prasad@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: mayank.prasad@stripped\ # 8i8xz73zlm79h70o # target_branch: file:///home/mayank/mysql-tree/mysql-trunk-wl5767/ # testament_sha1: 6344491f355d22422e71ec0c7c4fb6b89b0ea0cf # timestamp: 2011-05-10 23:57:01 +0530 # base_revision_id: marc.alff@stripped\ # o5yvvkt1vyvt7drg # # Begin bundle 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 --===============0496711808==--