diff options
author | Sergei Golubchik <serg@mariadb.org> | 2015-05-04 22:16:00 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2015-05-04 22:16:00 +0200 |
commit | d71d4119055f0184f5edd24e86fa3d6a5c71aa89 (patch) | |
tree | 99b335b2c1fe3dee66de346697c8a9bb468078d1 /storage/perfschema | |
parent | 05c002d0ffc003dfe6646f785dabef0c440da3d1 (diff) | |
download | mariadb-git-d71d4119055f0184f5edd24e86fa3d6a5c71aa89.tar.gz |
5.6.24
Diffstat (limited to 'storage/perfschema')
29 files changed, 338 insertions, 757 deletions
diff --git a/storage/perfschema/CMakeLists.txt b/storage/perfschema/CMakeLists.txt index b8f910a9539..8071476e1f6 100644 --- a/storage/perfschema/CMakeLists.txt +++ b/storage/perfschema/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2015, 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,29 +21,11 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ADD_DEFINITIONS(-DMYSQL_SERVER) -# Gen_pfs_lex_token -ADD_EXECUTABLE(gen_pfs_lex_token gen_pfs_lex_token.cc) -# gen_pfs_lex_token itself depends on ${CMAKE_CURRENT_BINARY_DIR}/sql/sql_yacc.h -ADD_DEPENDENCIES(gen_pfs_lex_token GenServerSource) - -ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pfs_lex_token.h - COMMAND gen_pfs_lex_token > pfs_lex_token.h - DEPENDS gen_pfs_lex_token -) - -SET(PFS_GEN_SOURCES - ${CMAKE_CURRENT_BINARY_DIR}/pfs_lex_token.h -) - -SET_SOURCE_FILES_PROPERTIES(${PFS_GEN_SOURCES} PROPERTIES GENERATED 1) - # # Maintainer: keep this list sorted, to avoid merge collisions. # Tip: ls -1 *.h, ls -1 *.cc # SET(PERFSCHEMA_SOURCES -${PFS_GEN_SOURCES} ha_perfschema.h cursor_by_account.h cursor_by_host.h diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index 876baa47fa6..7c556ba4407 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -4455,7 +4455,7 @@ get_thread_statement_locker_v1(PSI_statement_locker_state *state, pfs->m_sort_scan= 0; pfs->m_no_index_used= 0; pfs->m_no_good_index_used= 0; - digest_reset(& pfs->m_digest_storage); + pfs->m_digest_storage.reset(); /* New stages will have this statement as parent */ PFS_events_stages *child_stage= & pfs_thread->m_stage_current; @@ -4484,11 +4484,7 @@ get_thread_statement_locker_v1(PSI_statement_locker_state *state, if (flag_statements_digest) { - const CHARSET_INFO *cs= static_cast <const CHARSET_INFO*> (charset); flags|= STATE_FLAG_DIGEST; - state->m_digest_state.m_last_id_index= 0; - digest_reset(& state->m_digest_state.m_digest_storage); - state->m_digest_state.m_digest_storage.m_charset_number= cs->number; } state->m_discarded= false; @@ -4512,6 +4508,8 @@ get_thread_statement_locker_v1(PSI_statement_locker_state *state, state->m_no_index_used= 0; state->m_no_good_index_used= 0; + state->m_digest= NULL; + state->m_schema_name_length= 0; return reinterpret_cast<PSI_statement_locker*> (state); @@ -4781,11 +4779,11 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) PFS_statement_stat *event_name_array; uint index= klass->m_event_name_index; PFS_statement_stat *stat; - + /* Capture statement stats by digest. */ - PSI_digest_storage *digest_storage= NULL; + const sql_digest_storage *digest_storage= NULL; PFS_statement_stat *digest_stat= NULL; if (flags & STATE_FLAG_THREAD) @@ -4798,11 +4796,15 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) if (flags & STATE_FLAG_DIGEST) { - digest_storage= &state->m_digest_state.m_digest_storage; - /* Populate PFS_statements_digest_stat with computed digest information.*/ - digest_stat= find_or_create_digest(thread, digest_storage, - state->m_schema_name, - state->m_schema_name_length); + digest_storage= state->m_digest; + + if (digest_storage != NULL) + { + /* Populate PFS_statements_digest_stat with computed digest information.*/ + digest_stat= find_or_create_digest(thread, digest_storage, + state->m_schema_name, + state->m_schema_name_length); + } } if (flags & STATE_FLAG_EVENT) @@ -4839,7 +4841,7 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) pfs->m_timer_end= timer_end; pfs->m_end_event_id= thread->m_event_id; - if (flags & STATE_FLAG_DIGEST) + if (digest_storage != NULL) { /* The following columns in events_statement_current: @@ -4847,7 +4849,7 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) - DIGEST_TEXT are computed from the digest storage. */ - digest_copy(& pfs->m_digest_storage, digest_storage); + pfs->m_digest_storage.copy(digest_storage); } if (flag_events_statements_history) @@ -4870,11 +4872,15 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) if (thread != NULL) { /* Set digest stat. */ - digest_storage= &state->m_digest_state.m_digest_storage; - /* Populate statements_digest_stat with computed digest information. */ - digest_stat= find_or_create_digest(thread, digest_storage, - state->m_schema_name, - state->m_schema_name_length); + digest_storage= state->m_digest; + + if (digest_storage != NULL) + { + /* Populate statements_digest_stat with computed digest information. */ + digest_stat= find_or_create_digest(thread, digest_storage, + state->m_schema_name, + state->m_schema_name_length); + } } } @@ -4921,7 +4927,7 @@ static void end_statement_v1(PSI_statement_locker *locker, void *stmt_da) { digest_stat->aggregate_counted(); } - + digest_stat->m_lock_time+= state->m_lock_time; digest_stat->m_rows_sent+= state->m_rows_sent; digest_stat->m_rows_examined+= state->m_rows_examined; @@ -5106,6 +5112,39 @@ static void set_socket_thread_owner_v1(PSI_socket *socket) pfs_socket->m_thread_owner= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS); } +struct PSI_digest_locker* +pfs_digest_start_v1(PSI_statement_locker *locker) +{ + PSI_statement_locker_state *statement_state; + statement_state= reinterpret_cast<PSI_statement_locker_state*> (locker); + DBUG_ASSERT(statement_state != NULL); + + if (statement_state->m_discarded) + return NULL; + + if (statement_state->m_flags & STATE_FLAG_DIGEST) + { + return reinterpret_cast<PSI_digest_locker*> (locker); + } + + return NULL; +} + +void pfs_digest_end_v1(PSI_digest_locker *locker, const sql_digest_storage *digest) +{ + PSI_statement_locker_state *statement_state; + statement_state= reinterpret_cast<PSI_statement_locker_state*> (locker); + DBUG_ASSERT(statement_state != NULL); + DBUG_ASSERT(digest != NULL); + + if (statement_state->m_discarded) + return; + + if (statement_state->m_flags & STATE_FLAG_DIGEST) + { + statement_state->m_digest= digest; + } +} /** Implementation of the thread attribute connection interface @@ -5243,7 +5282,7 @@ PSI_v1 PFS_v1= set_socket_info_v1, set_socket_thread_owner_v1, pfs_digest_start_v1, - pfs_digest_add_token_v1, + pfs_digest_end_v1, set_thread_connect_attrs_v1, }; diff --git a/storage/perfschema/pfs_account.cc b/storage/perfschema/pfs_account.cc index 405364a23d3..e16c439ff07 100644 --- a/storage/perfschema/pfs_account.cc +++ b/storage/perfschema/pfs_account.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -527,9 +527,7 @@ void purge_account(PFS_thread *thread, PFS_account *account, account->m_key.m_key_length)); if (entry && (entry != MY_ERRPTR)) { - PFS_account *pfs; - pfs= *entry; - DBUG_ASSERT(pfs == account); + DBUG_ASSERT(*entry == account); if (account->get_refcount() == 0) { lf_hash_delete(&account_hash, pins, diff --git a/storage/perfschema/pfs_column_types.h b/storage/perfschema/pfs_column_types.h index 23ef946ee82..c70ca220d84 100644 --- a/storage/perfschema/pfs_column_types.h +++ b/storage/perfschema/pfs_column_types.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc index 8fbd5741565..21aa5f19230 100644 --- a/storage/perfschema/pfs_digest.cc +++ b/storage/perfschema/pfs_digest.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -28,54 +28,32 @@ #include "pfs_digest.h" #include "pfs_global.h" #include "table_helper.h" -#include "my_md5.h" #include "sql_lex.h" #include "sql_get_diagnostics.h" #include "sql_string.h" #include <string.h> -/* Generated code */ -#include "../sql/sql_yacc.h" -#include "../storage/perfschema/pfs_lex_token.h" - -/* Name pollution from sql/sql_lex.h */ -#ifdef LEX_YYSTYPE -#undef LEX_YYSTYPE -#endif - -#define LEX_YYSTYPE YYSTYPE - -/** - Token array : - Token array is an array of bytes to store tokens recieved during parsing. - Following is the way token array is formed. - - ...<non-id-token><non-id-token><id-token><id_len><id_text>... - - For Ex: - SELECT * FROM T1; - <SELECT_TOKEN><*><FROM_TOKEN><ID_TOKEN><2><T1> -*/ - ulong digest_max= 0; ulong digest_lost= 0; /** EVENTS_STATEMENTS_HISTORY_LONG circular buffer. */ PFS_statements_digest_stat *statements_digest_stat_array= NULL; +static unsigned char *statements_digest_token_array= NULL; /** Consumer flag for table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. */ bool flag_statements_digest= true; /** Current index in Stat array where new record is to be inserted. index 0 is reserved for "all else" case when entire array is full. */ -volatile uint32 digest_index= 1; +volatile uint32 digest_index; +bool digest_full= false; LF_HASH digest_hash; static bool digest_hash_inited= false; /** Initialize table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. - @param digest_sizing + @param param performance schema sizing */ int init_digest(const PFS_global_param *param) { @@ -87,19 +65,41 @@ int init_digest(const PFS_global_param *param) */ digest_max= param->m_digest_sizing; digest_lost= 0; + digest_index= 1; + digest_full= false; if (digest_max == 0) return 0; statements_digest_stat_array= - PFS_MALLOC_ARRAY(digest_max, PFS_statements_digest_stat, + PFS_MALLOC_ARRAY(digest_max, + PFS_statements_digest_stat, MYF(MY_ZEROFILL)); + if (unlikely(statements_digest_stat_array == NULL)) + { + cleanup_digest(); return 1; + } + + if (pfs_max_digest_length > 0) + { + statements_digest_token_array= + PFS_MALLOC_ARRAY(digest_max * pfs_max_digest_length, + unsigned char, + MYF(MY_ZEROFILL)); + + if (unlikely(statements_digest_token_array == NULL)) + { + cleanup_digest(); + return 1; + } + } for (index= 0; index < digest_max; index++) { - statements_digest_stat_array[index].reset_data(); + statements_digest_stat_array[index].reset_data(statements_digest_token_array + + index * pfs_max_digest_length, pfs_max_digest_length); } return 0; @@ -110,7 +110,9 @@ void cleanup_digest(void) { /* Free memory allocated to statements_digest_stat_array. */ pfs_free(statements_digest_stat_array); + pfs_free(statements_digest_token_array); statements_digest_stat_array= NULL; + statements_digest_token_array= NULL; } C_MODE_START @@ -170,10 +172,12 @@ static LF_PINS* get_digest_hash_pins(PFS_thread *thread) PFS_statement_stat* find_or_create_digest(PFS_thread *thread, - PSI_digest_storage *digest_storage, + const sql_digest_storage *digest_storage, const char *schema_name, uint schema_name_length) { + DBUG_ASSERT(digest_storage != NULL); + if (statements_digest_stat_array == NULL) return NULL; @@ -192,9 +196,8 @@ find_or_create_digest(PFS_thread *thread, PFS_digest_key hash_key; memset(& hash_key, 0, sizeof(hash_key)); /* Compute MD5 Hash of the tokens received. */ - compute_md5_hash((char *) hash_key.m_md5, - (char *) digest_storage->m_token_array, - digest_storage->m_byte_count); + compute_digest_md5(digest_storage, hash_key.m_md5); + memcpy((void*)& digest_storage->m_md5, &hash_key.m_md5, MD5_HASH_SIZE); /* Add the current schema to the key */ hash_key.m_schema_name_length= schema_name_length; if (schema_name_length > 0) @@ -227,8 +230,7 @@ search: lf_hash_search_unpin(pins); - /* Dirty read of digest_index */ - if (digest_index == 0) + if (digest_full) { /* digest_stat array is full. Add stat at index 0 and return. */ pfs= &statements_digest_stat_array[0]; @@ -244,7 +246,7 @@ search: if (safe_index >= digest_max) { /* The digest array is now full. */ - digest_index= 0; + digest_full= true; pfs= &statements_digest_stat_array[0]; if (pfs->m_first_seen == 0) @@ -263,7 +265,7 @@ search: Copy digest storage to statement_digest_stat_array so that it could be used later to generate digest text. */ - digest_copy(& pfs->m_digest_storage, digest_storage); + pfs->m_digest_storage.copy(digest_storage); pfs->m_first_seen= now; pfs->m_last_seen= now; @@ -313,9 +315,9 @@ void purge_digest(PFS_thread* thread, PFS_digest_key *hash_key) return; } -void PFS_statements_digest_stat::reset_data() +void PFS_statements_digest_stat::reset_data(unsigned char *token_array, uint length) { - digest_reset(& m_digest_storage); + m_digest_storage.reset(token_array, length); m_stat.reset(); m_first_seen= 0; m_last_seen= 0; @@ -345,7 +347,7 @@ void reset_esms_by_digest() for (index= 0; index < digest_max; index++) { statements_digest_stat_array[index].reset_index(thread); - statements_digest_stat_array[index].reset_data(); + statements_digest_stat_array[index].reset_data(statements_digest_token_array + index * pfs_max_digest_length, pfs_max_digest_length); } /* @@ -353,448 +355,6 @@ void reset_esms_by_digest() to be inserted in statements_digest_stat_array. */ digest_index= 1; + digest_full= false; } -/* - Iterate token array and updates digest_text. -*/ -void get_digest_text(char* digest_text, PSI_digest_storage* digest_storage) -{ - DBUG_ASSERT(digest_storage != NULL); - bool truncated= false; - int byte_count= digest_storage->m_byte_count; - char *digest_output= digest_text; - int bytes_needed= 0; - uint tok= 0; - int current_byte= 0; - lex_token_string *tok_data; - /* -4 is to make sure extra space for '...' and a '\0' at the end. */ - int bytes_available= COL_DIGEST_TEXT_SIZE - 4; - - if (byte_count <= 0 || byte_count > PSI_MAX_DIGEST_STORAGE_SIZE) - { - *digest_text= '\0'; - return; - } - - /* Convert text to utf8 */ - const CHARSET_INFO *from_cs= get_charset(digest_storage->m_charset_number, MYF(0)); - const CHARSET_INFO *to_cs= &my_charset_utf8_bin; - - if (from_cs == NULL) - { - /* - Can happen, as we do dirty reads on digest_storage, - which can be written to in another thread. - */ - *digest_text= '\0'; - return; - } - - /* - Max converted size is number of characters * max multibyte length of the - target charset, which is 4 for UTF8. - */ - const uint max_converted_size= PSI_MAX_DIGEST_STORAGE_SIZE * 4; - char id_buffer[max_converted_size]; - char *id_string; - int id_length; - bool convert_text= !my_charset_same(from_cs, to_cs); - - DBUG_ASSERT(byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); - - while ((current_byte < byte_count) && - (bytes_available > 0) && - !truncated) - { - current_byte= read_token(digest_storage, current_byte, &tok); - - if (tok <= 0 || tok >= array_elements(lex_token_array)) - { - *digest_text='\0'; - return; - } - - tok_data= &lex_token_array[tok]; - - switch (tok) - { - /* All identifiers are printed with their name. */ - case IDENT: - case IDENT_QUOTED: - { - char *id_ptr; - int id_len; - uint err_cs= 0; - - /* Get the next identifier from the storage buffer. */ - current_byte= read_identifier(digest_storage, current_byte, - &id_ptr, &id_len); - if (convert_text) - { - /* Verify that the converted text will fit. */ - if (to_cs->mbmaxlen*id_len > max_converted_size) - { - truncated= true; - break; - } - /* Convert identifier string into the storage character set. */ - id_length= my_convert(id_buffer, max_converted_size, to_cs, - id_ptr, id_len, from_cs, &err_cs); - id_string= id_buffer; - } - else - { - id_string= id_ptr; - id_length= id_len; - } - - if (id_length == 0 || err_cs != 0) - { - truncated= true; - break; - } - /* Copy the converted identifier into the digest string. */ - bytes_needed= id_length + (tok == IDENT ? 1 : 3); - if (bytes_needed <= bytes_available) - { - if (tok == IDENT_QUOTED) - *digest_output++= '`'; - if (id_length > 0) - { - memcpy(digest_output, id_string, id_length); - digest_output+= id_length; - } - if (tok == IDENT_QUOTED) - *digest_output++= '`'; - *digest_output++= ' '; - bytes_available-= bytes_needed; - } - else - { - truncated= true; - } - } - break; - - /* Everything else is printed as is. */ - default: - /* - Make sure not to overflow digest_text buffer. - +1 is to make sure extra space for ' '. - */ - int tok_length= tok_data->m_token_length; - bytes_needed= tok_length + 1; - - if (bytes_needed <= bytes_available) - { - strncpy(digest_output, tok_data->m_token_string, tok_length); - digest_output+= tok_length; - *digest_output++= ' '; - bytes_available-= bytes_needed; - } - else - { - truncated= true; - } - break; - } - } - - /* Truncate digest text in case of long queries. */ - if (digest_storage->m_full || truncated) - { - strcpy(digest_output, "..."); - digest_output+= 3; - } - - *digest_output= '\0'; -} - -static inline uint peek_token(const PSI_digest_storage *digest, int index) -{ - uint token; - DBUG_ASSERT(index >= 0); - DBUG_ASSERT(index + PFS_SIZE_OF_A_TOKEN <= digest->m_byte_count); - DBUG_ASSERT(digest->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); - - token= ((digest->m_token_array[index + 1])<<8) | digest->m_token_array[index]; - return token; -} - -/** - Function to read last two tokens from token array. If an identifier - is found, do not look for token before that. -*/ -static inline void peek_last_two_tokens(const PSI_digest_storage* digest_storage, - int last_id_index, uint *t1, uint *t2) -{ - int byte_count= digest_storage->m_byte_count; - int peek_index= byte_count - PFS_SIZE_OF_A_TOKEN; - - if (last_id_index <= peek_index) - { - /* Take last token. */ - *t1= peek_token(digest_storage, peek_index); - - peek_index-= PFS_SIZE_OF_A_TOKEN; - if (last_id_index <= peek_index) - { - /* Take 2nd token from last. */ - *t2= peek_token(digest_storage, peek_index); - } - else - { - *t2= TOK_PFS_UNUSED; - } - } - else - { - *t1= TOK_PFS_UNUSED; - *t2= TOK_PFS_UNUSED; - } -} - -struct PSI_digest_locker* pfs_digest_start_v1(PSI_statement_locker *locker) -{ - PSI_statement_locker_state *statement_state; - statement_state= reinterpret_cast<PSI_statement_locker_state*> (locker); - DBUG_ASSERT(statement_state != NULL); - - if (statement_state->m_discarded) - return NULL; - - if (statement_state->m_flags & STATE_FLAG_DIGEST) - { - PSI_digest_locker_state *digest_state; - digest_state= &statement_state->m_digest_state; - return reinterpret_cast<PSI_digest_locker*> (digest_state); - } - - return NULL; -} - -PSI_digest_locker* pfs_digest_add_token_v1(PSI_digest_locker *locker, - uint token, - OPAQUE_LEX_YYSTYPE *yylval) -{ - PSI_digest_locker_state *state= NULL; - PSI_digest_storage *digest_storage= NULL; - - state= reinterpret_cast<PSI_digest_locker_state*> (locker); - DBUG_ASSERT(state != NULL); - - digest_storage= &state->m_digest_storage; - - /* - Stop collecting further tokens if digest storage is full or - if END token is received. - */ - if (digest_storage->m_full || token == END_OF_INPUT) - return NULL; - - /* - Take last_token 2 tokens collected till now. These tokens will be used - in reduce for normalisation. Make sure not to consider ID tokens in reduce. - */ - uint last_token; - uint last_token2; - - switch (token) - { - case NUM: - case LONG_NUM: - case ULONGLONG_NUM: - case DECIMAL_NUM: - case FLOAT_NUM: - case BIN_NUM: - case HEX_NUM: - { - bool found_unary; - do - { - found_unary= false; - peek_last_two_tokens(digest_storage, state->m_last_id_index, - &last_token, &last_token2); - - if ((last_token == '-') || (last_token == '+')) - { - /* - We need to differentiate: - - a <unary minus> operator - - a <unary plus> operator - from - - a <binary minus> operator - - a <binary plus> operator - to only reduce "a = -1" to "a = ?", and not change "b - 1" to "b ?" - - Binary operators are found inside an expression, - while unary operators are found at the beginning of an expression, or after operators. - - To achieve this, every token that is followed by an <expr> expression - in the SQL grammar is flagged. - See sql/sql_yacc.yy - See sql/gen_lex_token.cc - - For example, - "(-1)" is parsed as "(", "-", NUM, ")", and lex_token_array["("].m_start_expr is true, - so reduction of the "-" NUM is done, the result is "(?)". - "(a-1)" is parsed as "(", ID, "-", NUM, ")", and lex_token_array[ID].m_start_expr is false, - so the operator is binary, no reduction is done, and the result is "(a-?)". - */ - if (lex_token_array[last_token2].m_start_expr) - { - /* - REDUCE: - TOK_PFS_GENERIC_VALUE := (UNARY_PLUS | UNARY_MINUS) (NUM | LOG_NUM | ... | FLOAT_NUM) - - REDUCE: - TOK_PFS_GENERIC_VALUE := (UNARY_PLUS | UNARY_MINUS) TOK_PFS_GENERIC_VALUE - */ - token= TOK_PFS_GENERIC_VALUE; - digest_storage->m_byte_count-= PFS_SIZE_OF_A_TOKEN; - found_unary= true; - } - } - } while (found_unary); - } - /* fall through, for case NULL_SYM below */ - case LEX_HOSTNAME: - case TEXT_STRING: - case NCHAR_STRING: - case PARAM_MARKER: - { - /* - REDUCE: - TOK_PFS_GENERIC_VALUE := BIN_NUM | DECIMAL_NUM | ... | ULONGLONG_NUM - */ - token= TOK_PFS_GENERIC_VALUE; - } - /* fall through */ - case NULL_SYM: - { - peek_last_two_tokens(digest_storage, state->m_last_id_index, - &last_token, &last_token2); - - if ((last_token2 == TOK_PFS_GENERIC_VALUE || - last_token2 == TOK_PFS_GENERIC_VALUE_LIST || - last_token2 == NULL_SYM) && - (last_token == ',')) - { - /* - REDUCE: - TOK_PFS_GENERIC_VALUE_LIST := - (TOK_PFS_GENERIC_VALUE|NULL_SYM) ',' (TOK_PFS_GENERIC_VALUE|NULL_SYM) - - REDUCE: - TOK_PFS_GENERIC_VALUE_LIST := - TOK_PFS_GENERIC_VALUE_LIST ',' (TOK_PFS_GENERIC_VALUE|NULL_SYM) - */ - digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN; - token= TOK_PFS_GENERIC_VALUE_LIST; - } - /* - Add this token or the resulting reduce to digest storage. - */ - store_token(digest_storage, token); - break; - } - case ')': - { - peek_last_two_tokens(digest_storage, state->m_last_id_index, - &last_token, &last_token2); - - if (last_token == TOK_PFS_GENERIC_VALUE && - last_token2 == '(') - { - /* - REDUCE: - TOK_PFS_ROW_SINGLE_VALUE := - '(' TOK_PFS_GENERIC_VALUE ')' - */ - digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN; - token= TOK_PFS_ROW_SINGLE_VALUE; - - /* Read last two tokens again */ - peek_last_two_tokens(digest_storage, state->m_last_id_index, - &last_token, &last_token2); - - if ((last_token2 == TOK_PFS_ROW_SINGLE_VALUE || - last_token2 == TOK_PFS_ROW_SINGLE_VALUE_LIST) && - (last_token == ',')) - { - /* - REDUCE: - TOK_PFS_ROW_SINGLE_VALUE_LIST := - TOK_PFS_ROW_SINGLE_VALUE ',' TOK_PFS_ROW_SINGLE_VALUE - - REDUCE: - TOK_PFS_ROW_SINGLE_VALUE_LIST := - TOK_PFS_ROW_SINGLE_VALUE_LIST ',' TOK_PFS_ROW_SINGLE_VALUE - */ - digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN; - token= TOK_PFS_ROW_SINGLE_VALUE_LIST; - } - } - else if (last_token == TOK_PFS_GENERIC_VALUE_LIST && - last_token2 == '(') - { - /* - REDUCE: - TOK_PFS_ROW_MULTIPLE_VALUE := - '(' TOK_PFS_GENERIC_VALUE_LIST ')' - */ - digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN; - token= TOK_PFS_ROW_MULTIPLE_VALUE; - - /* Read last two tokens again */ - peek_last_two_tokens(digest_storage, state->m_last_id_index, - &last_token, &last_token2); - - if ((last_token2 == TOK_PFS_ROW_MULTIPLE_VALUE || - last_token2 == TOK_PFS_ROW_MULTIPLE_VALUE_LIST) && - (last_token == ',')) - { - /* - REDUCE: - TOK_PFS_ROW_MULTIPLE_VALUE_LIST := - TOK_PFS_ROW_MULTIPLE_VALUE ',' TOK_PFS_ROW_MULTIPLE_VALUE - - REDUCE: - TOK_PFS_ROW_MULTIPLE_VALUE_LIST := - TOK_PFS_ROW_MULTIPLE_VALUE_LIST ',' TOK_PFS_ROW_MULTIPLE_VALUE - */ - digest_storage->m_byte_count-= 2*PFS_SIZE_OF_A_TOKEN; - token= TOK_PFS_ROW_MULTIPLE_VALUE_LIST; - } - } - /* - Add this token or the resulting reduce to digest storage. - */ - store_token(digest_storage, token); - break; - } - case IDENT: - case IDENT_QUOTED: - { - LEX_YYSTYPE *lex_token= (LEX_YYSTYPE*) yylval; - char *yytext= lex_token->lex_str.str; - int yylen= lex_token->lex_str.length; - - /* Add this token and identifier string to digest storage. */ - store_token_identifier(digest_storage, token, yylen, yytext); - - /* Update the index of last identifier found. */ - state->m_last_id_index= digest_storage->m_byte_count; - break; - } - default: - { - /* Add this token to digest storage. */ - store_token(digest_storage, token); - break; - } - } - - return locker; -} diff --git a/storage/perfschema/pfs_digest.h b/storage/perfschema/pfs_digest.h index 03f534b3d7e..9d021737c44 100644 --- a/storage/perfschema/pfs_digest.h +++ b/storage/perfschema/pfs_digest.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2015, 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 @@ -24,23 +24,19 @@ #include "pfs_column_types.h" #include "lf.h" #include "pfs_stat.h" - -#define PFS_SIZE_OF_A_TOKEN 2 +#include "sql_digest.h" extern bool flag_statements_digest; extern ulong digest_max; extern ulong digest_lost; struct PFS_thread; -/* Fixed, per MD5 hash. */ -#define PFS_MD5_SIZE 16 - /** Structure to store a MD5 hash value (digest) for a statement. */ struct PFS_digest_key { - unsigned char m_md5[PFS_MD5_SIZE]; + unsigned char m_md5[MD5_HASH_SIZE]; char m_schema_name[NAME_LEN]; uint m_schema_name_length; }; @@ -52,7 +48,7 @@ struct PFS_ALIGNED PFS_statements_digest_stat PFS_digest_key m_digest_key; /** Digest Storage. */ - PSI_digest_storage m_digest_storage; + sql_digest_storage m_digest_storage; /** Statement stat. */ PFS_statement_stat m_stat; @@ -62,7 +58,7 @@ struct PFS_ALIGNED PFS_statements_digest_stat ulonglong m_last_seen; /** Reset data for this record. */ - void reset_data(); + void reset_data(unsigned char* token_array, uint length); /** Reset data and remove index for this record. */ void reset_index(PFS_thread *thread); }; @@ -73,147 +69,15 @@ void cleanup_digest(); int init_digest_hash(void); void cleanup_digest_hash(void); PFS_statement_stat* find_or_create_digest(PFS_thread *thread, - PSI_digest_storage *digest_storage, + const sql_digest_storage *digest_storage, const char *schema_name, uint schema_name_length); -void get_digest_text(char *digest_text, PSI_digest_storage *digest_storage); - void reset_esms_by_digest(); /* Exposing the data directly, for iterators. */ extern PFS_statements_digest_stat *statements_digest_stat_array; -/* Instrumentation callbacks for pfs.cc */ - -struct PSI_digest_locker *pfs_digest_start_v1(PSI_statement_locker *locker); -PSI_digest_locker *pfs_digest_add_token_v1(PSI_digest_locker *locker, - uint token, - OPAQUE_LEX_YYSTYPE *yylval); - -static inline void digest_reset(PSI_digest_storage *digest) -{ - digest->m_full= false; - digest->m_byte_count= 0; - digest->m_charset_number= 0; -} - -static inline void digest_copy(PSI_digest_storage *to, const PSI_digest_storage *from) -{ - if (from->m_byte_count > 0) - { - to->m_full= from->m_full; - to->m_byte_count= from->m_byte_count; - to->m_charset_number= from->m_charset_number; - DBUG_ASSERT(to->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); - memcpy(to->m_token_array, from->m_token_array, to->m_byte_count); - } - else - { - DBUG_ASSERT(from->m_byte_count == 0); - to->m_full= false; - to->m_byte_count= 0; - to->m_charset_number= 0; - } -} - -/** - Read a single token from token array. -*/ -inline int read_token(PSI_digest_storage *digest_storage, - int index, uint *tok) -{ - int safe_byte_count= digest_storage->m_byte_count; - - if (index + PFS_SIZE_OF_A_TOKEN <= safe_byte_count && - safe_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE) - { - unsigned char *src= & digest_storage->m_token_array[index]; - *tok= src[0] | (src[1] << 8); - return index + PFS_SIZE_OF_A_TOKEN; - } - - /* The input byte stream is exhausted. */ - *tok= 0; - return PSI_MAX_DIGEST_STORAGE_SIZE + 1; -} - -/** - Store a single token in token array. -*/ -inline void store_token(PSI_digest_storage* digest_storage, uint token) -{ - DBUG_ASSERT(digest_storage->m_byte_count >= 0); - DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); - - if (digest_storage->m_byte_count + PFS_SIZE_OF_A_TOKEN <= PSI_MAX_DIGEST_STORAGE_SIZE) - { - unsigned char* dest= & digest_storage->m_token_array[digest_storage->m_byte_count]; - dest[0]= token & 0xff; - dest[1]= (token >> 8) & 0xff; - digest_storage->m_byte_count+= PFS_SIZE_OF_A_TOKEN; - } - else - { - digest_storage->m_full= true; - } -} - -/** - Read an identifier from token array. -*/ -inline int read_identifier(PSI_digest_storage* digest_storage, - int index, char ** id_string, int *id_length) -{ - int new_index; - DBUG_ASSERT(index <= digest_storage->m_byte_count); - DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); - - /* - token + length + string are written in an atomic way, - so we do always expect a length + string here - */ - unsigned char *src= & digest_storage->m_token_array[index]; - uint length= src[0] | (src[1] << 8); - *id_string= (char *) (src + 2); - *id_length= length; - - new_index= index + PFS_SIZE_OF_A_TOKEN + length; - DBUG_ASSERT(new_index <= digest_storage->m_byte_count); - return new_index; -} - -/** - Store an identifier in token array. -*/ -inline void store_token_identifier(PSI_digest_storage* digest_storage, - uint token, - uint id_length, const char *id_name) -{ - DBUG_ASSERT(digest_storage->m_byte_count >= 0); - DBUG_ASSERT(digest_storage->m_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE); - - uint bytes_needed= 2 * PFS_SIZE_OF_A_TOKEN + id_length; - if (digest_storage->m_byte_count + bytes_needed <= PSI_MAX_DIGEST_STORAGE_SIZE) - { - unsigned char* dest= & digest_storage->m_token_array[digest_storage->m_byte_count]; - /* Write the token */ - dest[0]= token & 0xff; - dest[1]= (token >> 8) & 0xff; - /* Write the string length */ - dest[2]= id_length & 0xff; - dest[3]= (id_length >> 8) & 0xff; - /* Write the string data */ - if (id_length > 0) - memcpy((char *)(dest + 4), id_name, id_length); - digest_storage->m_byte_count+= bytes_needed; - } - else - { - digest_storage->m_full= true; - } -} - extern LF_HASH digest_hash; #endif diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc index df4418b4bae..d114c2286d4 100644 --- a/storage/perfschema/pfs_engine_table.cc +++ b/storage/perfschema/pfs_engine_table.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -1415,12 +1415,64 @@ bool pfs_show_status(handlerton *hton, THD *thd, name= "host_cache.size"; size= sizeof(Host_entry); break; + case 154: + name= "(history_long_statements_digest_token_array).row_count"; + size= events_statements_history_long_size; + break; + case 155: + name= "(history_long_statements_digest_token_array).row_size"; + size= pfs_max_digest_length; + break; + case 156: + name= "(history_long_statements_digest_token_array).memory"; + size= events_statements_history_long_size * pfs_max_digest_length; + total_memory+= size; + break; + case 157: + name= "(history_statements_digest_token_array).row_count"; + size= thread_max * events_statements_history_per_thread; + break; + case 158: + name= "(history_statements_digest_token_array).row_size"; + size= pfs_max_digest_length; + break; + case 159: + name= "(history_statements_digest_token_array).memory"; + size= thread_max * events_statements_history_per_thread * pfs_max_digest_length; + total_memory+= size; + break; + case 160: + name= "(current_statements_digest_token_array).row_count"; + size= thread_max * statement_stack_max; + break; + case 161: + name= "(current_statements_digest_token_array).row_size"; + size= pfs_max_digest_length; + break; + case 162: + name= "(current_statements_digest_token_array).memory"; + size= thread_max * statement_stack_max * pfs_max_digest_length; + total_memory+= size; + break; + case 163: + name= "(statements_digest_token_array).row_count"; + size= digest_max; + break; + case 164: + name= "(statements_digest_token_array).row_size"; + size= pfs_max_digest_length; + break; + case 165: + name= "(statements_digest_token_array).memory"; + size= digest_max * pfs_max_digest_length; + total_memory+= size; + break; /* This case must be last, for aggregation in total_memory. */ - case 154: + case 166: name= "performance_schema.memory"; size= total_memory; /* This will fail if something is not advertised here */ diff --git a/storage/perfschema/pfs_events_statements.cc b/storage/perfschema/pfs_events_statements.cc index 07810d26dc4..dc34755d747 100644 --- a/storage/perfschema/pfs_events_statements.cc +++ b/storage/perfschema/pfs_events_statements.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -44,6 +44,7 @@ bool events_statements_history_long_full= false; volatile uint32 events_statements_history_long_index= 0; /** EVENTS_STATEMENTS_HISTORY_LONG circular buffer. */ PFS_events_statements *events_statements_history_long_array= NULL; +static unsigned char *h_long_stmts_digest_token_array= NULL; /** Initialize table EVENTS_STATEMENTS_HISTORY_LONG. @@ -51,6 +52,7 @@ PFS_events_statements *events_statements_history_long_array= NULL; */ int init_events_statements_history_long(uint events_statements_history_long_sizing) { + uint index; events_statements_history_long_size= events_statements_history_long_sizing; events_statements_history_long_full= false; PFS_atomic::store_u32(&events_statements_history_long_index, 0); @@ -62,20 +64,50 @@ int init_events_statements_history_long(uint events_statements_history_long_sizi PFS_MALLOC_ARRAY(events_statements_history_long_size, PFS_events_statements, MYF(MY_ZEROFILL)); - return (events_statements_history_long_array ? 0 : 1); + if (events_statements_history_long_array == NULL) + { + cleanup_events_statements_history_long(); + return 1; + } + + if (pfs_max_digest_length > 0) + { + h_long_stmts_digest_token_array= + PFS_MALLOC_ARRAY(events_statements_history_long_size * pfs_max_digest_length, + unsigned char, MYF(MY_ZEROFILL)); + if (h_long_stmts_digest_token_array == NULL) + { + cleanup_events_statements_history_long(); + return 1; + } + } + + for (index= 0; index < events_statements_history_long_size; index++) + { + events_statements_history_long_array[index].m_digest_storage.reset(h_long_stmts_digest_token_array + + index * pfs_max_digest_length, pfs_max_digest_length); + } + + return 0; } /** Cleanup table EVENTS_STATEMENTS_HISTORY_LONG. */ void cleanup_events_statements_history_long(void) { pfs_free(events_statements_history_long_array); + pfs_free(h_long_stmts_digest_token_array); events_statements_history_long_array= NULL; + h_long_stmts_digest_token_array= NULL; } static inline void copy_events_statements(PFS_events_statements *dest, const PFS_events_statements *source) { - memcpy(dest, source, sizeof(PFS_events_statements)); + /* Copy all attributes except DIGEST */ + memcpy(dest, source, my_offsetof(PFS_events_statements, m_digest_storage)); + + /* Copy DIGEST */ + dest->m_digest_storage.copy(& source->m_digest_storage); } /** diff --git a/storage/perfschema/pfs_events_statements.h b/storage/perfschema/pfs_events_statements.h index 5d90250c618..3637e4ca764 100644 --- a/storage/perfschema/pfs_events_statements.h +++ b/storage/perfschema/pfs_events_statements.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -88,8 +88,12 @@ struct PFS_events_statements : public PFS_events ulonglong m_no_index_used; /** Optimizer metric, number of 'no good index used'. */ ulonglong m_no_good_index_used; - /** Statement digest. */ - PSI_digest_storage m_digest_storage; + /** + Statement digest. + This underlying token array storage pointer is immutable, + and always point to pre allocated memory. + */ + sql_digest_storage m_digest_storage; }; void insert_events_statements_history(PFS_thread *thread, PFS_events_statements *statement); diff --git a/storage/perfschema/pfs_host.cc b/storage/perfschema/pfs_host.cc index 0c6f5cf3627..3d8565d9d17 100644 --- a/storage/perfschema/pfs_host.cc +++ b/storage/perfschema/pfs_host.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -353,9 +353,7 @@ void purge_host(PFS_thread *thread, PFS_host *host) 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); + DBUG_ASSERT(*entry == host); if (host->get_refcount() == 0) { lf_hash_delete(&host_hash, pins, diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index cf0e6fd56f8..d35da1979f2 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -94,6 +94,7 @@ ulong events_stages_history_per_thread; /** Number of EVENTS_STATEMENTS_HISTORY records per thread. */ ulong events_statements_history_per_thread; uint statement_stack_max; +uint pfs_max_digest_length= 0; /** Number of locker lost. @sa LOCKER_STACK_SIZE. */ ulong locker_lost= 0; /** Number of statement lost. @sa STATEMENT_STACK_SIZE. */ @@ -176,6 +177,8 @@ static PFS_events_waits *thread_waits_history_array= NULL; static PFS_events_stages *thread_stages_history_array= NULL; static PFS_events_statements *thread_statements_history_array= NULL; static PFS_events_statements *thread_statements_stack_array= NULL; +static unsigned char *current_stmts_digest_token_array= NULL; +static unsigned char *history_stmts_digest_token_array= NULL; static char *thread_session_connect_attrs_array= NULL; /** Hash table for instrumented files. */ @@ -190,6 +193,9 @@ static bool filename_hash_inited= false; */ int init_instruments(const PFS_global_param *param) { + PFS_events_statements *pfs_stmt; + unsigned char *pfs_tokens; + uint thread_waits_history_sizing; uint thread_stages_history_sizing; uint thread_statements_history_sizing; @@ -215,6 +221,9 @@ int init_instruments(const PFS_global_param *param) file_handle_max= param->m_file_handle_sizing; file_handle_full= false; file_handle_lost= 0; + + pfs_max_digest_length= param->m_max_digest_length; + table_max= param->m_table_sizing; table_full= false; table_lost= 0; @@ -254,6 +263,9 @@ int init_instruments(const PFS_global_param *param) * session_connect_attrs_size_per_thread; session_connect_attrs_lost= 0; + size_t current_digest_tokens_sizing= param->m_thread_sizing * pfs_max_digest_length * statement_stack_max; + size_t history_digest_tokens_sizing= param->m_thread_sizing * pfs_max_digest_length * events_statements_history_per_thread; + mutex_array= NULL; rwlock_array= NULL; cond_array= NULL; @@ -266,6 +278,8 @@ int init_instruments(const PFS_global_param *param) thread_stages_history_array= NULL; thread_statements_history_array= NULL; thread_statements_stack_array= NULL; + current_stmts_digest_token_array= NULL; + history_stmts_digest_token_array= NULL; thread_instr_class_waits_array= NULL; thread_instr_class_stages_array= NULL; thread_instr_class_statements_array= NULL; @@ -407,6 +421,22 @@ int init_instruments(const PFS_global_param *param) return 1; } + if (current_digest_tokens_sizing > 0) + { + current_stmts_digest_token_array= + (unsigned char *)pfs_malloc(current_digest_tokens_sizing, MYF(MY_ZEROFILL)); + if (unlikely(current_stmts_digest_token_array == NULL)) + return 1; + } + + if (history_digest_tokens_sizing > 0) + { + history_stmts_digest_token_array= + (unsigned char *)pfs_malloc(history_digest_tokens_sizing, MYF(MY_ZEROFILL)); + if (unlikely(history_stmts_digest_token_array == NULL)) + return 1; + } + for (index= 0; index < thread_max; index++) { thread_array[index].m_waits_history= @@ -427,6 +457,22 @@ int init_instruments(const PFS_global_param *param) &thread_session_connect_attrs_array[index * session_connect_attrs_size_per_thread]; } + for (index= 0; index < thread_statements_stack_sizing; index++) + { + pfs_stmt= & thread_statements_stack_array[index]; + + pfs_tokens= & current_stmts_digest_token_array[index * pfs_max_digest_length]; + pfs_stmt->m_digest_storage.reset(pfs_tokens, pfs_max_digest_length); + } + + for (index= 0; index < thread_statements_history_sizing; index++) + { + pfs_stmt= & thread_statements_history_array[index]; + + pfs_tokens= & history_stmts_digest_token_array[index * pfs_max_digest_length]; + pfs_stmt->m_digest_storage.reset(pfs_tokens, pfs_max_digest_length); + } + if (stage_class_max > 0) { global_instr_class_stages_array= @@ -497,6 +543,10 @@ void cleanup_instruments(void) global_instr_class_statements_array= NULL; pfs_free(thread_session_connect_attrs_array); thread_session_connect_attrs_array=NULL; + pfs_free(current_stmts_digest_token_array); + current_stmts_digest_token_array= NULL; + pfs_free(history_stmts_digest_token_array); + history_stmts_digest_token_array= NULL; } C_MODE_START diff --git a/storage/perfschema/pfs_instr.h b/storage/perfschema/pfs_instr.h index bd2fe0e4afd..a639f94fada 100644 --- a/storage/perfschema/pfs_instr.h +++ b/storage/perfschema/pfs_instr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -298,6 +298,8 @@ struct PFS_ALIGNED PFS_socket : public PFS_instr /** Max size of the statements stack. */ extern uint statement_stack_max; +/** Max size of the digests token array. */ +extern uint pfs_max_digest_length; /** @def PFS_MAX_ALLOC_RETRY diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc index 093f772915a..cc5e52f379d 100644 --- a/storage/perfschema/pfs_server.cc +++ b/storage/perfschema/pfs_server.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 diff --git a/storage/perfschema/pfs_server.h b/storage/perfschema/pfs_server.h index aa5dd6862fa..ba7d892554b 100644 --- a/storage/perfschema/pfs_server.h +++ b/storage/perfschema/pfs_server.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -197,6 +197,8 @@ struct PFS_global_param /** Maximum number of session attribute strings per thread */ long m_session_connect_attrs_sizing; + uint m_max_digest_length; + /** Sizing hints, for auto tuning. */ PFS_sizing_hints m_hints; }; diff --git a/storage/perfschema/pfs_user.cc b/storage/perfschema/pfs_user.cc index 9f53702dd86..0d89948843c 100644 --- a/storage/perfschema/pfs_user.cc +++ b/storage/perfschema/pfs_user.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -346,9 +346,7 @@ void purge_user(PFS_thread *thread, PFS_user *user) 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); + DBUG_ASSERT(*entry == user); if (user->get_refcount() == 0) { lf_hash_delete(&user_hash, pins, diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc index 6d95cdd77bb..0d926b13373 100644 --- a/storage/perfschema/table_events_statements.cc +++ b/storage/perfschema/table_events_statements.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -302,7 +302,7 @@ table_events_statements_common::table_events_statements_common @param statement the statement the cursor is reading */ void table_events_statements_common::make_row_part_1(PFS_events_statements *statement, - PSI_digest_storage *digest) + sql_digest_storage *digest) { const char *base; const char *safe_source_file; @@ -367,46 +367,40 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat m_row.m_sort_scan= statement->m_sort_scan; m_row.m_no_index_used= statement->m_no_index_used; m_row.m_no_good_index_used= statement->m_no_good_index_used; - /* + /* Making a copy of digest storage. */ - digest_copy(digest, & statement->m_digest_storage); + digest->copy(& statement->m_digest_storage); m_row_exists= true; return; } -void table_events_statements_common::make_row_part_2(PSI_digest_storage *digest) +void table_events_statements_common::make_row_part_2(const sql_digest_storage *digest) { /* Filling up statement digest information. */ - int safe_byte_count= digest->m_byte_count; + uint safe_byte_count= digest->m_byte_count; if (safe_byte_count > 0 && - safe_byte_count <= PSI_MAX_DIGEST_STORAGE_SIZE) + safe_byte_count <= pfs_max_digest_length) { - PFS_digest_key md5; - compute_md5_hash((char *) md5.m_md5, - (char *) digest->m_token_array, - safe_byte_count); - /* Generate the DIGEST string from the MD5 digest */ - MD5_HASH_TO_STRING(md5.m_md5, + MD5_HASH_TO_STRING(digest->m_md5, m_row.m_digest.m_digest); m_row.m_digest.m_digest_length= MD5_HASH_TO_STRING_LENGTH; /* Generate the DIGEST_TEXT string from the token array */ - get_digest_text(m_row.m_digest.m_digest_text, digest); - m_row.m_digest.m_digest_text_length= strlen(m_row.m_digest.m_digest_text); + compute_digest_text(digest, &m_row.m_digest.m_digest_text); - if (m_row.m_digest.m_digest_text_length == 0) + if (m_row.m_digest.m_digest_text.length() == 0) m_row.m_digest.m_digest_length= 0; } else { m_row.m_digest.m_digest_length= 0; - m_row.m_digest.m_digest_text_length= 0; + m_row.m_digest.m_digest_text.length(0); } return; @@ -491,9 +485,9 @@ int table_events_statements_common::read_row_values(TABLE *table, f->set_null(); break; case 11: /* DIGEST_TEXT */ - if (m_row.m_digest.m_digest_text_length > 0) - set_field_longtext_utf8(f, m_row.m_digest.m_digest_text, - m_row.m_digest.m_digest_text_length); + if (m_row.m_digest.m_digest_text.length() > 0) + set_field_longtext_utf8(f, m_row.m_digest.m_digest_text.ptr(), + m_row.m_digest.m_digest_text.length()); else f->set_null(); break; @@ -710,11 +704,11 @@ int table_events_statements_current::rnd_pos(const void *pos) void table_events_statements_current::make_row(PFS_thread *pfs_thread, PFS_events_statements *statement) { - PSI_digest_storage digest; + sql_digest_storage digest; pfs_lock lock; pfs_lock stmt_lock; - digest_reset(&digest); + digest.reset(m_token_array, MAX_DIGEST_STORAGE_SIZE); /* Protect this reader against thread termination. */ pfs_thread->m_lock.begin_optimistic_lock(&lock); /* Protect this reader against writing on statement information. */ @@ -838,10 +832,10 @@ int table_events_statements_history::rnd_pos(const void *pos) void table_events_statements_history::make_row(PFS_thread *pfs_thread, PFS_events_statements *statement) { - PSI_digest_storage digest; + sql_digest_storage digest; pfs_lock lock; - digest_reset(&digest); + digest.reset(m_token_array, MAX_DIGEST_STORAGE_SIZE); /* Protect this reader against thread termination. */ pfs_thread->m_lock.begin_optimistic_lock(&lock); @@ -942,9 +936,9 @@ int table_events_statements_history_long::rnd_pos(const void *pos) void table_events_statements_history_long::make_row(PFS_events_statements *statement) { - PSI_digest_storage digest; + sql_digest_storage digest; - digest_reset(&digest); + digest.reset(m_token_array, MAX_DIGEST_STORAGE_SIZE); table_events_statements_common::make_row_part_1(statement, &digest); table_events_statements_common::make_row_part_2(&digest); diff --git a/storage/perfschema/table_events_statements.h b/storage/perfschema/table_events_statements.h index e33c6b505bd..a42bbcb2e5a 100644 --- a/storage/perfschema/table_events_statements.h +++ b/storage/perfschema/table_events_statements.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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 @@ -175,14 +175,15 @@ protected: {} void make_row_part_1(PFS_events_statements *statement, - PSI_digest_storage *digest); + sql_digest_storage *digest); - void make_row_part_2(PSI_digest_storage *digest); + void make_row_part_2(const sql_digest_storage *digest); /** Current row. */ row_events_statements m_row; /** True if the current row exists. */ bool m_row_exists; + unsigned char m_token_array[MAX_DIGEST_STORAGE_SIZE]; }; /** Table PERFORMANCE_SCHEMA.EVENTS_STATEMENTS_CURRENT. */ diff --git a/storage/perfschema/table_helper.cc b/storage/perfschema/table_helper.cc index 9c10a3ecc88..c9def1bfc74 100644 --- a/storage/perfschema/table_helper.cc +++ b/storage/perfschema/table_helper.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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_host.h" #include "pfs_user.h" #include "pfs_account.h" +#include "pfs_instr.h" int PFS_host_row::make_row(PFS_host *pfs) { @@ -109,8 +110,8 @@ int PFS_digest_row::make_row(PFS_statements_digest_stat* pfs) if (m_schema_name_length > 0) memcpy(m_schema_name, pfs->m_digest_key.m_schema_name, m_schema_name_length); - int safe_byte_count= pfs->m_digest_storage.m_byte_count; - if (safe_byte_count > PSI_MAX_DIGEST_STORAGE_SIZE) + uint safe_byte_count= pfs->m_digest_storage.m_byte_count; + if (safe_byte_count > pfs_max_digest_length) safe_byte_count= 0; /* @@ -124,23 +125,22 @@ int PFS_digest_row::make_row(PFS_statements_digest_stat* pfs) Calculate digest from MD5 HASH collected to be shown as DIGEST in this row. */ - MD5_HASH_TO_STRING(pfs->m_digest_key.m_md5, m_digest); + MD5_HASH_TO_STRING(pfs->m_digest_storage.m_md5, m_digest); m_digest_length= MD5_HASH_TO_STRING_LENGTH; /* Calculate digest_text information from the token array collected to be shown as DIGEST_TEXT column. */ - get_digest_text(m_digest_text, &pfs->m_digest_storage); - m_digest_text_length= strlen(m_digest_text); + compute_digest_text(&pfs->m_digest_storage, &m_digest_text); - if (m_digest_text_length == 0) + if (m_digest_text.length() == 0) m_digest_length= 0; } else { m_digest_length= 0; - m_digest_text_length= 0; + m_digest_text.length(0); } return 0; @@ -165,9 +165,9 @@ void PFS_digest_row::set_field(uint index, Field *f) f->set_null(); break; case 2: /* DIGEST_TEXT */ - if (m_digest_text_length > 0) - PFS_engine_table::set_field_longtext_utf8(f, m_digest_text, - m_digest_text_length); + if (m_digest_text.length() > 0) + PFS_engine_table::set_field_longtext_utf8(f, m_digest_text.ptr(), + m_digest_text.length()); else f->set_null(); break; diff --git a/storage/perfschema/table_helper.h b/storage/perfschema/table_helper.h index 76bb289c73b..b1377eb9748 100644 --- a/storage/perfschema/table_helper.h +++ b/storage/perfschema/table_helper.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -136,9 +136,7 @@ struct PFS_digest_row /** Length in bytes of @c m_digest. */ uint m_digest_length; /** Column DIGEST_TEXT. */ - char m_digest_text[COL_DIGEST_TEXT_SIZE]; - /** Length in bytes of @c m_digest_text. */ - uint m_digest_text_length; + String m_digest_text; /** Build a row from a memory buffer. */ int make_row(PFS_statements_digest_stat*); diff --git a/storage/perfschema/unittest/CMakeLists.txt b/storage/perfschema/unittest/CMakeLists.txt index b237d6b4ee0..b4f1c58181c 100644 --- a/storage/perfschema/unittest/CMakeLists.txt +++ b/storage/perfschema/unittest/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2015, 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,9 +23,13 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ADD_DEFINITIONS(-DMYSQL_SERVER ${SSL_DEFINES}) +ADD_CONVENIENCE_LIBRARY(pfs_server_stubs pfs_server_stubs.cc) + +ADD_DEPENDENCIES(pfs_server_stubs GenError) + MACRO (PFS_ADD_TEST name) ADD_EXECUTABLE(${name}-t ${name}-t.cc) - TARGET_LINK_LIBRARIES(${name}-t mytap perfschema mysys) + TARGET_LINK_LIBRARIES(${name}-t mytap perfschema mysys pfs_server_stubs) ADD_TEST(${name} ${name}-t) ENDMACRO() diff --git a/storage/perfschema/unittest/pfs-t.cc b/storage/perfschema/unittest/pfs-t.cc index 6e63a18f174..8b24cee9eaf 100644 --- a/storage/perfschema/unittest/pfs-t.cc +++ b/storage/perfschema/unittest/pfs-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -26,7 +26,6 @@ #include "stub_print_error.h" #include "stub_pfs_defaults.h" -#include "stub_server_misc.h" /* test helpers, to simulate the setup */ @@ -112,6 +111,7 @@ void test_bootstrap() param.m_events_statements_history_long_sizing= 0; param.m_digest_sizing= 0; param.m_session_connect_attrs_sizing= 0; + param.m_max_digest_length= 0; boot= initialize_performance_schema(& param); ok(boot != NULL, "boot"); @@ -170,6 +170,7 @@ PSI * load_perfschema() param.m_events_statements_history_long_sizing= 0; param.m_digest_sizing= 0; param.m_session_connect_attrs_sizing= 0; + param.m_max_digest_length= 0; /* test_bootstrap() covered this, assuming it just works */ boot= initialize_performance_schema(& param); @@ -1514,6 +1515,7 @@ void test_event_name_index() param.m_events_statements_history_long_sizing= 0; param.m_digest_sizing= 0; param.m_session_connect_attrs_sizing= 0; + param.m_max_digest_length= 0; param.m_mutex_sizing= 0; param.m_rwlock_sizing= 0; diff --git a/storage/perfschema/unittest/pfs_account-oom-t.cc b/storage/perfschema/unittest/pfs_account-oom-t.cc index 7574de542f8..ef8a7c195e0 100644 --- a/storage/perfschema/unittest/pfs_account-oom-t.cc +++ b/storage/perfschema/unittest/pfs_account-oom-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2015, 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 @@ -22,7 +22,6 @@ #include <tap.h> #include "stub_pfs_global.h" -#include "stub_server_misc.h" #include <string.h> /* memset */ diff --git a/storage/perfschema/unittest/pfs_host-oom-t.cc b/storage/perfschema/unittest/pfs_host-oom-t.cc index 32d9c23cbde..6627dd48df2 100644 --- a/storage/perfschema/unittest/pfs_host-oom-t.cc +++ b/storage/perfschema/unittest/pfs_host-oom-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2015, 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 @@ -22,7 +22,6 @@ #include <tap.h> #include "stub_pfs_global.h" -#include "stub_server_misc.h" #include <string.h> /* memset */ diff --git a/storage/perfschema/unittest/pfs_instr-oom-t.cc b/storage/perfschema/unittest/pfs_instr-oom-t.cc index 1ec198511c9..161060aa6bf 100644 --- a/storage/perfschema/unittest/pfs_instr-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr-oom-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -22,7 +22,6 @@ #include <tap.h> #include "stub_pfs_global.h" -#include "stub_server_misc.h" #include <string.h> /* memset */ diff --git a/storage/perfschema/unittest/pfs_instr-t.cc b/storage/perfschema/unittest/pfs_instr-t.cc index 43c143fe30f..3cc4c48388d 100644 --- a/storage/perfschema/unittest/pfs_instr-t.cc +++ b/storage/perfschema/unittest/pfs_instr-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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,8 +23,6 @@ #include <memory.h> -#include "stub_server_misc.h" - void test_no_instruments() { int rc; @@ -62,6 +60,7 @@ void test_no_instruments() param.m_events_statements_history_long_sizing= 0; param.m_digest_sizing= 0; param.m_session_connect_attrs_sizing= 0; + param.m_max_digest_length= 0; init_event_name_sizing(& param); rc= init_instruments(& param); @@ -121,6 +120,7 @@ void test_no_instances() param.m_events_statements_history_long_sizing= 0; param.m_digest_sizing= 0; param.m_session_connect_attrs_sizing= 0; + param.m_max_digest_length= 0; init_event_name_sizing(& param); rc= init_instruments(& param); @@ -261,6 +261,7 @@ void test_with_instances() param.m_events_statements_history_long_sizing= 0; param.m_digest_sizing= 0; param.m_session_connect_attrs_sizing= 0; + param.m_max_digest_length= 0; init_event_name_sizing(& param); rc= init_instruments(& param); diff --git a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc index f83d017f231..e98250d8567 100644 --- a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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 @@ -20,7 +20,6 @@ #include <tap.h> #include "stub_pfs_global.h" -#include "stub_server_misc.h" void test_oom() { diff --git a/storage/perfschema/unittest/pfs_instr_class-t.cc b/storage/perfschema/unittest/pfs_instr_class-t.cc index 85dec2dccc4..ee483312e3c 100644 --- a/storage/perfschema/unittest/pfs_instr_class-t.cc +++ b/storage/perfschema/unittest/pfs_instr_class-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2015, 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,8 +21,6 @@ #include <pfs_global.h> #include <tap.h> -#include "stub_server_misc.h" - void test_no_registration() { int rc; diff --git a/storage/perfschema/unittest/stub_server_misc.h b/storage/perfschema/unittest/pfs_server_stubs.cc index 946da533727..a8f417e390b 100644 --- a/storage/perfschema/unittest/stub_server_misc.h +++ b/storage/perfschema/unittest/pfs_server_stubs.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, 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,12 +17,19 @@ Minimal code to be able to link a unit test. */ +#include "my_global.h" +#include "m_ctype.h" +#include "sql_class.h" +#include "sql_show.h" + +struct sql_digest_storage; + volatile bool ready_to_exit= false; uint lower_case_table_names= 0; CHARSET_INFO *files_charset_info= NULL; -extern "C" void compute_md5_hash(char *, const char *, int) +void compute_digest_md5(const sql_digest_storage *, unsigned char *) { } diff --git a/storage/perfschema/unittest/pfs_user-oom-t.cc b/storage/perfschema/unittest/pfs_user-oom-t.cc index 1faf29b753a..0e4c5eb3411 100644 --- a/storage/perfschema/unittest/pfs_user-oom-t.cc +++ b/storage/perfschema/unittest/pfs_user-oom-t.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2015, 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 @@ -22,7 +22,6 @@ #include <tap.h> #include "stub_pfs_global.h" -#include "stub_server_misc.h" #include <string.h> /* memset */ |