From: Mayank Prasad Date: August 18 2011 12:49pm Subject: bzr push into mysql-trunk-wl5767 branch (mayank.prasad:3375 to 3376) WL#5767 List-Archive: http://lists.mysql.com/commits/140708 Message-Id: <201108181249.p7ICnPAV015536@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3376 Mayank Prasad 2011-08-18 WL#5767 : PERFORMANCE SCHEMA, statement digest Description: 1. Code to store tokens passed from Lexer to PS. 2. Code to calculate MD5 for the tokens recieved. 3. Code to calculate digest for the statement parsed. modified: sql/sql_lex.cc storage/perfschema/pfs.cc storage/perfschema/pfs_digest.cc storage/perfschema/pfs_digest.h 3375 Mayank Prasad 2011-08-08 wl#5767 : PERFORMANCE SCHEMA, statement digest Details: additional Code changes for getting tokens from Lexer to PS function. modified: sql/sql_lex.cc sql/sql_lex.h === modified file 'sql/sql_lex.cc' --- a/sql/sql_lex.cc 2011-08-08 06:10:03 +0000 +++ b/sql/sql_lex.cc 2011-08-18 12:47:38 +0000 @@ -28,6 +28,30 @@ #include "sp.h" #include "sp_head.h" +#define PASS_TOKEN_TO_PS(_token,_yychar,_yylen) \ + /* + Passing token to PS function to calculate statement digest + for this statement. + */ \ + if( _token != 0 ) \ + { \ + uint yylen=0; \ + char *yychar; \ + if( _token != END_OF_INPUT ) \ + { \ + /* + get the length of processed token and make sure it doesn't exceed + TOCK_NAME_LENGTH. If it does, truncate it to TOCK_NAME_LENGTH. + */ \ + yylen= _yylen!=0 ? _yylen : lip->yyLength_PS(); \ + yylen= yylenget_cpp_tok_start(); \ + } \ + PSI_server->digest_add_token(lip->m_digest_psi,_token,yychar,yylen); \ + } \ + + static int lex_one_token(void *arg, void *yythd); /* @@ -870,6 +894,7 @@ int MYSQLlex(void *arg, void *yythd) lip->lookahead_token= -1; *yylval= *(lip->lookahead_yylval); lip->lookahead_yylval= NULL; + PASS_TOKEN_TO_PS(token,NULL,0); return token; } @@ -887,8 +912,10 @@ int MYSQLlex(void *arg, void *yythd) token= lex_one_token(arg, yythd); switch(token) { case CUBE_SYM: + PASS_TOKEN_TO_PS(WITH_CUBE_SYM,"WITH CUBE",9); return WITH_CUBE_SYM; case ROLLUP_SYM: + PASS_TOKEN_TO_PS(WITH_ROLLUP_SYM,"WITH ROLLUP",11); return WITH_ROLLUP_SYM; default: /* @@ -897,6 +924,7 @@ int MYSQLlex(void *arg, void *yythd) lip->lookahead_yylval= lip->yylval; lip->yylval= NULL; lip->lookahead_token= token; + PASS_TOKEN_TO_PS(WITH,"WITH",4); return WITH; } break; @@ -904,24 +932,7 @@ int MYSQLlex(void *arg, void *yythd) break; } - /* - Passing token to PS function to calculate statement digest - for this statement. - */ - if(token != END_OF_INPUT && token != 0) - { - uint yylen=0,yylen_temp=0; - char yychar[TOCK_NAME_LENGTH]={'\0'}; - /* - get the length of processed token and make sure it doesn't exceed - TOCK_NAME_LENGTH. If it does, truncate it to TOCK_NAME_LENGTH. - */ - yylen_temp = lip->yyLength_PS(); - yylen = yylen_temp < TOCK_NAME_LENGTH ? yylen_temp : TOCK_NAME_LENGTH-1; - - strncpy(yychar, lip->get_cpp_tok_start(), yylen); - PSI_server->digest_add_token(lip->m_digest_psi,token,yychar,yylen); - } + PASS_TOKEN_TO_PS(token,NULL,0); return token; } === modified file 'storage/perfschema/pfs.cc' --- a/storage/perfschema/pfs.cc 2011-08-02 20:02:22 +0000 +++ b/storage/perfschema/pfs.cc 2011-08-18 12:47:38 +0000 @@ -35,6 +35,8 @@ #include "pfs_setup_actor.h" #include "pfs_setup_object.h" #include "sql_error.h" +#include "my_md5.h" +#include "pfs_digest.h" /** @page PAGE_PERFORMANCE_SCHEMA The Performance Schema main page @@ -996,6 +998,8 @@ static inline int mysql_mutex_lock(...) /** EVENT bit in the state flags bitfield. */ #define STATE_FLAG_EVENT (1<<2) +#define PFS_MAX_TOKEN_COUNT 1024 + pthread_key(PFS_thread*, THR_PFS); bool THR_PFS_initialized= false; @@ -1087,6 +1091,21 @@ static enum_operation_type table_lock_op OPERATION_TYPE_TL_WRITE_EXTERNAL /* PFS_TL_WRITE_EXTERNAL */ }; +/** + Structure to store token count/array for a statement. +*/ +struct { + uint m_token_count; + uint m_token_array[PFS_MAX_TOKEN_COUNT]; + } typedef PFS_digest_storage; +PFS_digest_storage digest_storage; + +/** + Structure to store a MD5 hash value (digest) for a statement. +*/ +struct { + unsigned char m_md5[16]; + }typedef PFS_digest_hash; /** Build the prefix name of a class of instruments in a category. @@ -4251,10 +4270,48 @@ static void digest_add_token_v1(PSI_dige char *yytext, int yylen) { - //printf("\n inside digest_add_token_v1 \n"); //printf("\n Got Token [%s,%d]\n",yytext,yylen); - /* TBD. */ + + /* + Token 403 is END_OF_INPUT. Once it is recieved, it means all token in + statement text are recieved. + */ + if( token == 403 ) + { + PFS_digest_hash digest; + char digest_str[COL_DIGEST_SIZE]={'\0'}; + /* + Calculate MD5 Hash of the tokens recieved. + */ + MY_MD5_HASH(digest.m_md5, (unsigned char *)&digest_storage, (uint) sizeof(digest_storage)); + /* + Write MD5 hash value in a string to be used as DIGEST for the statement. + */ + sprintf(digest_str, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x", + digest.m_md5[0], digest.m_md5[1], digest.m_md5[2], + digest.m_md5[3], digest.m_md5[4], digest.m_md5[5], + digest.m_md5[6], digest.m_md5[7], digest.m_md5[8], + digest.m_md5[9], digest.m_md5[10], digest.m_md5[11], + digest.m_md5[12], digest.m_md5[13], digest.m_md5[14], + digest.m_md5[15]); + + printf(" Computed Digest= [%s]\n",digest_str); + /* + Populate PFS_statements_digest_stat with this information. + TODO: create DIGEST_TEXT from tokens and pass it. + */ + insert_statement_digest(digest_str, (char*)"DIGEST_TEXT"); + digest_storage.m_token_count= 0; + } + else + { + /* Add this token to digest storage. */ + DBUG_ASSERT(digest_storage.m_token_count < PFS_MAX_TOKEN_COUNT); + digest_storage.m_token_array[digest_storage.m_token_count]= token; + digest_storage.m_token_count++; + } } static void digest_end_v1(PSI_digest_locker *locker) === modified file 'storage/perfschema/pfs_digest.cc' --- a/storage/perfschema/pfs_digest.cc 2011-08-02 20:02:22 +0000 +++ b/storage/perfschema/pfs_digest.cc 2011-08-18 12:47:38 +0000 @@ -21,12 +21,15 @@ #include "pfs_digest.h" #include "my_sys.h" #include "pfs_global.h" +#include unsigned int statements_digest_size= 0; /** EVENTS_STATEMENTS_HISTORY_LONG circular buffer. */ PFS_statements_digest_stat *statements_digest_stat_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. */ +int digest_index= 0; /** Initialize table EVENTS_STATEMENTS_SUMMARY_BY_DIGEST. @@ -59,3 +62,24 @@ void cleanup_digest(void) pfs_free(statements_digest_stat_array); statements_digest_stat_array= NULL; } + +void insert_statement_digest(char* digest, char* digest_text) +{ + /* Lookup LF_HASH for the computed DIGEST. */ + + /* If stmt digest already exists, update stat and return */ + + /* if statement digest doesn't exist, add a new record in the stat array */ + memcpy(statements_digest_stat_array[digest_index].digest, digest, + COL_DIGEST_SIZE); + memcpy(statements_digest_stat_array[digest_index].digest_text, digest_text, + COL_DIGEST_TEXT_SIZE); + /* Rounding Buffer. Overwrite first entry if last all slots are full. */ + digest_index= (digest_index+1)%statements_digest_size; +} + +void reset_esms_by_digest() +{ + /*TBD*/ +} + === modified file 'storage/perfschema/pfs_digest.h' --- a/storage/perfschema/pfs_digest.h 2011-08-02 20:02:22 +0000 +++ b/storage/perfschema/pfs_digest.h 2011-08-18 12:47:38 +0000 @@ -21,15 +21,23 @@ Statement Digest data structures (declarations). */ +#include "pfs_column_types.h" + extern bool flag_statements_digest; /** A statement stat record based on digest. */ struct PFS_statements_digest_stat { /* TBD */ + char digest[COL_DIGEST_SIZE]; + char digest_text[COL_DIGEST_TEXT_SIZE]; }; +void insert_statement_digest(char*,char*); + int init_digest(unsigned int digest_sizing); void cleanup_digest(); +void reset_esms_by_digest(); + #endif No bundle (reason: useless for push emails).