From: Mayank Prasad Date: February 6 2012 12:09pm Subject: bzr push into mysql-trunk-wl5767 branch (mayank.prasad:3431 to 3432) WL#5767 List-Archive: http://lists.mysql.com/commits/142767 Message-Id: <201202061209.q16C9568007502@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3432 Mayank Prasad 2012-02-06 WL#5767 : Performance Schema, Statements Digest Details: - Added new flag m_full in PFS_digest_storage. - Modified code to make sure not to overflow digest_text buffer while generating digest text. modified: mysql-test/suite/perfschema/r/statements_digest_long_query.result storage/perfschema/pfs_digest.cc storage/perfschema/pfs_digest.h storage/perfschema/table_events_statements.cc storage/perfschema/table_helper.cc 3431 Mayank Prasad 2012-02-06 WL#5767: Performance Schema, Statements Digest Details: - Modified PSI_digest_locker_state_v1 to have last_id_index. - Modified PFS_digest_storage to have only Token Stream. - Modified PFS_statements_digest_stat to have Digest Hash. modified: include/mysql/psi/psi.h include/mysql/psi/psi_abi_v1.h.pp storage/perfschema/pfs.cc storage/perfschema/pfs_digest.cc storage/perfschema/pfs_digest.h storage/perfschema/table_events_statements.cc storage/perfschema/table_helper.cc === modified file 'mysql-test/suite/perfschema/r/statements_digest_long_query.result' --- a/mysql-test/suite/perfschema/r/statements_digest_long_query.result 2012-02-02 17:31:41 +0000 +++ b/mysql-test/suite/perfschema/r/statements_digest_long_query.result 2012-02-06 12:08:15 +0000 @@ -10,4 +10,4 @@ select DIGEST, DIGEST_TEXT, COUNT_STAR f DIGEST DIGEST_TEXT COUNT_STAR NULL NULL 0 553022034e2aab0f TRUNCATE TABLE events_statements_summa 1 -ba5a568f3d3dcc06 SELECT ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ! ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? ... 1 +ba5a568f3d3dcc06 SELECT ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ! ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ? + ... 1 === modified file 'storage/perfschema/pfs_digest.cc' --- a/storage/perfschema/pfs_digest.cc 2012-02-06 09:30:53 +0000 +++ b/storage/perfschema/pfs_digest.cc 2012-02-06 12:08:15 +0000 @@ -207,6 +207,7 @@ find_or_create_digest(PFS_thread* thread used later to generate digest text. */ pfs->m_digest_storage.m_byte_count= digest_storage->m_byte_count; + pfs->m_digest_storage.m_full= digest_storage->m_full; /* Copy token array. */ memcpy(pfs->m_digest_storage.m_token_array, digest_storage->m_token_array, PFS_MAX_DIGEST_STORAGE_SIZE); @@ -285,6 +286,7 @@ void PFS_statements_digest_stat::reset() m_digest_storage.m_byte_count= 0; m_digest_storage.m_token_array[0]= '\0'; + m_digest_storage.m_full= false; m_stat.reset(); purge_digest(thread, m_digest_hash.m_md5); m_digest_hash.m_md5[0]= '\0'; @@ -317,53 +319,68 @@ void reset_esms_by_digest() /* This function, iterates token array and updates digest_text. */ -void get_digest_text(char* digest_text, char* token_array, int byte_count) +void get_digest_text(char* digest_text, PFS_digest_storage* digest_storage) { uint tok= 0; int current_byte= 0; char *digest_text_start= digest_text; lex_token_string *tok_data; + char* token_array= digest_storage->m_token_array; + int byte_count= digest_storage->m_byte_count; + /* -4 is to make sure extra space for ... and a '\0' at the end. */ + int available_bytes_to_write= COL_DIGEST_TEXT_SIZE-4; DBUG_ASSERT(byte_count <= PFS_MAX_DIGEST_STORAGE_SIZE); while(current_byte0) { read_token(&tok, ¤t_byte, token_array); tok_data= & lex_token_array[tok]; - + switch (tok) { /* All identifiers are printed with their name. */ case IDENT: case IDENT_QUOTED: - read_identifier(&digest_text, ¤t_byte, token_array); + read_identifier(&digest_text, ¤t_byte, + token_array, (uint)available_bytes_to_write); *digest_text= ' '; digest_text++; break; /* Everything else is printed as is. */ default: + /* + Make sure not to overflow digest_text buffer while writing + this token string. + +/-1 is to make sure extra space for ' '. + */ + int length= available_bytes_to_write >= tok_data->m_token_length+1? + tok_data->m_token_length: + available_bytes_to_write-1; strncpy(digest_text, tok_data->m_token_string, - tok_data->m_token_length); - digest_text+= tok_data->m_token_length; + length); + digest_text+= length; *digest_text= ' '; digest_text++; } + + available_bytes_to_write-= digest_text-digest_text_start; + digest_text_start= digest_text; } /* Truncate digest text in case of long queries. */ - if(digest_text-digest_text_start == COL_DIGEST_TEXT_SIZE-3) + if(digest_storage->m_full) { strcpy(digest_text,"..."); + digest_text+= 3; } - else - { - *digest_text= '\0'; - } + + *digest_text= '\0'; } struct PSI_digest_locker* pfs_digest_start_v1(PSI_statement_locker *locker) @@ -410,6 +427,7 @@ struct PSI_digest_locker* pfs_digest_sta state->m_last_id_index= 0; while(digest_storage->m_byte_count) digest_storage->m_token_array[--digest_storage->m_byte_count]= 0; + digest_storage->m_full= false; /* Set digest_locker_state's statement info pointer. @@ -441,8 +459,9 @@ PSI_digest_locker* pfs_digest_add_token_ PFS_SIZE_OF_A_TOKEN) { /* - If digest storage record is full, do nothing. + If digest storage record is full. */ + digest_storage->m_full= true; return NULL; } === modified file 'storage/perfschema/pfs_digest.h' --- a/storage/perfschema/pfs_digest.h 2012-02-06 09:30:53 +0000 +++ b/storage/perfschema/pfs_digest.h 2012-02-06 12:08:15 +0000 @@ -45,6 +45,7 @@ struct { on which digest is to be calculated. */ struct { + bool m_full; int m_byte_count; char m_token_array[PFS_MAX_DIGEST_STORAGE_SIZE]; } typedef PFS_digest_storage; @@ -85,9 +86,7 @@ PFS_statements_digest_stat* find_or_crea PFS_digest_hash, PFS_digest_storage*); -void get_digest_text(char* digest_text, - char* token_array, - int byte_count); +void get_digest_text(char* digest_text, PFS_digest_storage*); void reset_esms_by_digest(); @@ -105,17 +104,18 @@ PSI_digest_locker* pfs_digest_add_token_ /** Function to read a single token from token array. */ -inline void read_token(uint *dest, int *index, char *src) +inline void read_token(uint *tok, int *index, char *src) { unsigned short sh; int remaining_bytes= PFS_MAX_DIGEST_STORAGE_SIZE - *index; DBUG_ASSERT(remaining_bytes >= 0); - /* Make sure we have enough space to read a token. */ + /* Make sure we have enough space to read a token from. + */ if(remaining_bytes >= PFS_SIZE_OF_A_TOKEN) { sh= ((0x00ff & src[*index + 1])<<8) | (0x00ff & src[*index]); - *dest= (uint)(sh); + *tok= (uint)(sh); *index= *index + PFS_SIZE_OF_A_TOKEN; } } @@ -131,7 +131,7 @@ inline void store_token(PFS_digest_stora int remaining_bytes= PFS_MAX_DIGEST_STORAGE_SIZE - *index; DBUG_ASSERT(remaining_bytes >= 0); - /* Make sure we have enough space to store a token. */ + /* Make sure we have enough space to write a token to. */ if(remaining_bytes >= PFS_SIZE_OF_A_TOKEN) { dest[*index]= (sh) & 0xff; @@ -144,23 +144,27 @@ inline void store_token(PFS_digest_stora /** Function to read an identifier from token array. */ -inline void read_identifier(char **dest, int *index, char *src) +inline void read_identifier(char **dest, int *index, char *src, + uint available_bytes_to_write) { uint length; int remaining_bytes= PFS_MAX_DIGEST_STORAGE_SIZE - *index; DBUG_ASSERT(remaining_bytes >= 0); /* Read ID's length. - Make sure that space, to read ID's length, is available. + Make sure that space to read ID's length from, is available. */ if(remaining_bytes >= PFS_SIZE_OF_A_TOKEN) { read_token(&length, index, src); /* - While storing ID length, it has already been stored - in a way that ID doesn't go beyond the storage size, - so no need to check length here. + Make sure not to overflow digest_text buffer while writing + identifier name. + +/-1 is to make sure extra space for ' '. */ + length= available_bytes_to_write >= length+1 ? + length : + available_bytes_to_write-1; strncpy(*dest, src + *index, length); *index= *index + length; *dest= *dest + length; === modified file 'storage/perfschema/table_events_statements.cc' --- a/storage/perfschema/table_events_statements.cc 2012-02-06 09:30:53 +0000 +++ b/storage/perfschema/table_events_statements.cc 2012-02-06 12:08:15 +0000 @@ -383,9 +383,7 @@ void table_events_statements_common::mak Caclulate digest_text information from the token array collected to be shown as DIGEST_TEXT column. */ - get_digest_text(m_row.m_digest.m_digest_text, - pfs->m_digest_storage.m_token_array, - pfs->m_digest_storage.m_byte_count); + get_digest_text(m_row.m_digest.m_digest_text, &pfs->m_digest_storage); m_row.m_digest.m_digest_text_length= strlen(m_row.m_digest.m_digest_text); } else === modified file 'storage/perfschema/table_helper.cc' --- a/storage/perfschema/table_helper.cc 2012-02-06 09:30:53 +0000 +++ b/storage/perfschema/table_helper.cc 2012-02-06 12:08:15 +0000 @@ -121,9 +121,7 @@ int PFS_digest_row::make_row(PFS_stateme Caclulate 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_token_array, - pfs->m_digest_storage.m_byte_count); + get_digest_text(m_digest_text, &pfs->m_digest_storage); m_digest_text_length= strlen(m_digest_text); } No bundle (reason: useless for push emails).