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= yylen<TOCK_NAME_LENGTH ? yylen : TOCK_NAME_LENGTH-1; \
+ yychar= _yychar!=NULL ? (char*)_yychar : \
+ (char*)lip->get_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 <string.h>
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).
| Thread |
|---|
| • bzr push into mysql-trunk-wl5767 branch (mayank.prasad:3375 to 3376) WL#5767 | Mayank Prasad | 22 Aug |