3385 Mayank Prasad 2011-10-04
WL#5767 : statement digest, performance schema
Details:
- Addressed review comments from Marc.
modified:
sql/sql_lex.cc
sql/sql_lex.h
storage/perfschema/pfs.cc
storage/perfschema/pfs_digest.cc
storage/perfschema/pfs_digest.h
storage/perfschema/pfs_events_statements.h
storage/perfschema/table_esms_by_digest.cc
storage/perfschema/table_helper.cc
3384 Mayank Prasad 2011-09-15
wl#5767 : performance schema, statement digest
Details:
- Code for populating statement_current, statement_history and
statement_history_long tables with captured digest information.
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/pfs_events_statements.h
storage/perfschema/table_events_statements.cc
=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc 2011-09-07 21:27:46 +0000
+++ b/sql/sql_lex.cc 2011-10-04 12:16:34 +0000
@@ -29,32 +29,28 @@
#include "sp_head.h"
#define PASS_TOKEN_TO_PS(_token,_yychar,_yylen) \
- if(lip->m_digest_psi != NULL) \
- { \
- /*
- Passing token to PS function to calculate statement digest
- for this statement.
- */ \
- if( _token != 0 ) \
- { \
- uint yylen= 0; \
- char *yychar= NULL; \
- 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 ? (char*)_yychar : \
- (char*)lip->get_cpp_tok_start(); \
- } \
- PSI_server->digest_add_token(lip->m_digest_psi,_token,yychar,yylen); \
- } \
+ /*
+ Passing token to PS function to calculate statement digest
+ for this statement.
+ */ \
+ if( _token != 0 ) \
+ { \
+ uint yylen= 0; \
+ char *yychar= NULL; \
+ 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 ? (char*)_yychar : \
+ (char*)lip->get_cpp_tok_start(); \
+ } \
+ PSI_CALL(digest_add_token)(lip->m_digest_psi,_token,yychar,yylen); \
}
-
static int lex_one_token(void *arg, void *yythd);
/*
@@ -198,15 +194,8 @@ bool Lex_input_stream::init(THD *thd,
reset(buff, length);
/* DIGEST_START */
- if( thd->m_statement_psi != NULL )
- {
- m_digest_psi= PSI_server->digest_start(thd->m_statement_psi);
- }
- else
- {
- m_digest_psi= NULL;
- }
-
+ m_digest_psi= PSI_server->digest_start(thd->m_statement_psi);
+
return FALSE;
}
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2011-09-07 10:38:59 +0000
+++ b/sql/sql_lex.h 2011-10-04 12:16:34 +0000
@@ -2600,12 +2600,6 @@ public:
{
m_lip.reset(found_semicolon, length);
m_yacc.reset();
-
- if( m_lip.m_digest_psi != NULL )
- {
- /* DIGEST_END */
- PSI_server->digest_end(m_lip.m_digest_psi);
- }
}
};
=== modified file 'storage/perfschema/pfs.cc'
--- a/storage/perfschema/pfs.cc 2011-09-15 12:22:08 +0000
+++ b/storage/perfschema/pfs.cc 2011-10-04 12:16:34 +0000
@@ -1172,13 +1172,6 @@ static enum_operation_type socket_operat
};
/**
- 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.
For example, this function builds the string 'wait/sync/mutex/sql/' from
a prefix 'wait/sync/mutex' and a category 'sql'.
@@ -4797,7 +4790,7 @@ static struct PSI_digest_locker* digest_
/*
If current statement is not instrumented
*/
- if( !(flag_thread_instrumentation && flag_events_statements_current) )
+ if(!locker || !(flag_thread_instrumentation && flag_events_statements_current))
{
return NULL;
}
@@ -4822,9 +4815,10 @@ static struct PSI_digest_locker* digest_
digest_storage= &pfs->m_digest_storage;
/*
- Initialize token count to 0.
- */
- digest_storage->m_token_count= 0;
+ Initialize token array and token count to 0.
+ */
+ while(digest_storage->m_token_count)
+ digest_storage->m_token_array[--digest_storage->m_token_count]= 0;
/*
Set digest_locker_state's digest storage pointer.
@@ -4843,6 +4837,9 @@ static void digest_add_token_v1(PSI_dige
PFS_events_statements *pfs;
PFS_digest_storage *digest_storage;
+ if(!locker)
+ return;
+
state= reinterpret_cast<PSI_digest_locker_state*> (locker);
DBUG_ASSERT(state != NULL);
@@ -4855,39 +4852,9 @@ static void digest_add_token_v1(PSI_dige
*/
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(PFS_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]);
-
- /*
- TODO: create DIGEST_TEXT from tokens and pass it to
- insert_statement_digest() below. Hard coded to
- "DIGEST_TEXT" as of now.
- */
-
- /*
- Populate PFS_statements_digest_stat with computed digest information.
- */
- PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
- pfs->statement_digest_stat_ptr=
- search_insert_statement_digest(pfs_thread,
- digest_str,
- (char*)"DIGEST_TEXT");
+ /* DIGEST_End */
+ PSI_CALL(digest_end)(locker);
+ return;
}
else if( digest_storage->m_token_count >= PFS_MAX_TOKEN_COUNT )
{
@@ -4912,14 +4879,36 @@ static void digest_end_v1(PSI_digest_loc
PFS_events_statements *pfs;
PFS_digest_storage *digest_storage;
+ if(!locker)
+ return;
+
state= reinterpret_cast<PSI_digest_locker_state*> (locker);
DBUG_ASSERT(state != NULL);
pfs= reinterpret_cast<PFS_events_statements *>(state->m_statement);
digest_storage= &pfs->m_digest_storage;
- /* reset token count to 0 */
- digest_storage->m_token_count= 0;
+ //printf("\n statement_text = [%s]\n",pfs->m_sqltext);
+
+ /*
+ Calculate MD5 Hash of the tokens recieved.
+ */
+ MY_MD5_HASH(digest_storage->m_digest_hash.m_md5, (unsigned char *)digest_storage->m_token_array,
+ (uint) sizeof(digest_storage->m_token_array));
+
+ /*
+ Populate PFS_statements_digest_stat with computed digest information.
+ */
+ PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+ pfs->statement_digest_stat_ptr=
+ search_insert_statement_digest(pfs_thread,
+ digest_storage->m_digest_hash.m_md5,
+ pfs->m_sqltext,
+ pfs->m_sqltext_length);
+ /*
+ Not resetting digest_storage->m_token_count to 0 here as it will be done in
+ digest_start.
+ */
}
/**
=== modified file 'storage/perfschema/pfs_digest.cc'
--- a/storage/perfschema/pfs_digest.cc 2011-09-15 12:22:08 +0000
+++ b/storage/perfschema/pfs_digest.cc 2011-10-04 12:16:34 +0000
@@ -28,8 +28,11 @@ unsigned int statements_digest_size= 0;
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;
+/**
+ 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.
+*/
+int digest_index= 1;
static LF_HASH digest_hash;
static bool digest_hash_inited= false;
@@ -77,8 +80,8 @@ static uchar *digest_hash_get_key(const
DBUG_ASSERT(typed_entry != NULL);
digest= *typed_entry;
DBUG_ASSERT(digest != NULL);
- *length= digest->m_key.m_key_length;
- result= digest->m_key.m_hash_key;
+ *length= 16;
+ result= digest->m_md5_hash.m_md5;
return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
}
C_MODE_END
@@ -114,34 +117,18 @@ static LF_PINS* get_digest_hash_pins(PFS
{
if (unlikely(thread->m_digest_hash_pins == NULL))
{
- if (! digest_hash_inited)
+ if (!digest_hash_inited)
return NULL;
thread->m_digest_hash_pins= lf_hash_get_pins(&digest_hash);
}
return thread->m_digest_hash_pins;
}
-static void set_digest_key(PFS_digest_key *key,
- const char *digest, uint digest_length)
-{
- DBUG_ASSERT(digest_length <= COL_DIGEST_SIZE);
-
- char *ptr= &key->m_hash_key[0];
- if (digest_length > 0)
- {
- memcpy(ptr, digest, digest_length);
- ptr+= digest_length;
- }
- ptr[0]= 0;
- ptr++;
- key->m_key_length= ptr - &key->m_hash_key[0];
-}
-
-
PFS_statements_digest_stat*
search_insert_statement_digest(PFS_thread* thread,
- char* digest,
- char* digest_text)
+ unsigned char* hash_key,
+ char* digest_text,
+ unsigned int digest_text_length)
{
/* get digest pin. */
LF_PINS *pins= get_digest_hash_pins(thread);
@@ -150,42 +137,54 @@ search_insert_statement_digest(PFS_threa
return NULL;
}
- /* make new digest key. */
- PFS_digest_key key;
- set_digest_key(&key, digest, strlen(digest));
-
PFS_statements_digest_stat **entry;
+ PFS_statements_digest_stat *pfs;
/* Lookup LF_HASH using this new key. */
entry= reinterpret_cast<PFS_statements_digest_stat**>
(lf_hash_search(&digest_hash, pins,
- key.m_hash_key, key.m_key_length));
+ hash_key, 16));
if(!entry)
{
/*
- If statement digest entry doesn't exist, add a new record in the
- digest stat array.
+ If statement digest entry doesn't exist.
*/
//printf("\n Doesn't Exist. Adding new entry. \n");
- PFS_statements_digest_stat *pfs;
+ if(digest_index==0)
+ {
+ /*
+ digest_stat array is full. Add stat at index 0 and return.
+ */
+ pfs= &statements_digest_stat_array[0];
+ //TODO
+ return pfs;
+ }
+
+ /*
+ Add a new record in digest stat array.
+ */
pfs= &statements_digest_stat_array[digest_index];
- /* Set digest. */
- memcpy(pfs->m_digest, digest, COL_DIGEST_SIZE);
- pfs->m_digest_length= strlen(digest);
-
/* Set digest text. */
- memcpy(pfs->m_digest_text, digest_text, COL_DIGEST_TEXT_SIZE);
- pfs->m_digest_text_length= strlen(digest_text);
+ memcpy(pfs->m_digest_text, digest_text, digest_text_length);
+ pfs->m_digest_text_length= digest_text_length;
- /* Set digest key. */
- memcpy(pfs->m_key.m_hash_key, key.m_hash_key, COL_DIGEST_SIZE);
- pfs->m_key.m_key_length= key.m_key_length;
+ /* Set digest hash/LF Hash search key. */
+ memcpy(pfs->m_md5_hash.m_md5, hash_key, 16);
+
+ /* Increment index. */
+ digest_index++;
- /* Rounding Buffer. Overwrite first entry if all slots are full. */
- digest_index= (digest_index+1)%statements_digest_size;
+ if(digest_index%statements_digest_size == 0)
+ {
+ /*
+ Digest stat array is full. Now all stat for all further
+ entries will go into index 0.
+ */
+ digest_index= 0;
+ }
/* Add this new digest into LF_HASH */
int res;
@@ -204,7 +203,6 @@ search_insert_statement_digest(PFS_threa
If stmt digest already exists, update stat and return
*/
//printf("\n Already Exists \n");
- PFS_statements_digest_stat *pfs;
pfs= *entry;
lf_hash_search_unpin(pins);
return pfs;
=== modified file 'storage/perfschema/pfs_digest.h'
--- a/storage/perfschema/pfs_digest.h 2011-09-15 12:22:08 +0000
+++ b/storage/perfschema/pfs_digest.h 2011-10-04 12:16:34 +0000
@@ -28,19 +28,6 @@
extern bool flag_statements_digest;
-struct PFS_digest_key
-{
- /**
- Hash search key.
- This has to be a string for LF_HASH,
- the format is "<digest><0x00>"
- */
- char m_hash_key[COL_DIGEST_SIZE + 1];
- unsigned int m_key_length;
-};
-
-
-
/** A statement digest stat record. */
struct PFS_statements_digest_stat
{
@@ -49,7 +36,10 @@ struct PFS_statements_digest_stat
char m_digest_text[COL_DIGEST_TEXT_SIZE];
unsigned int m_digest_text_length;
- PFS_digest_key m_key;
+ /**
+ Digest hash/LF Hash search key.
+ */
+ PFS_digest_hash m_md5_hash;
};
@@ -60,7 +50,8 @@ void cleanup_digest();
int init_digest_hash(void);
void cleanup_digest_hash(void);
PFS_statements_digest_stat* search_insert_statement_digest(PFS_thread*,
- char*, char*);
+ unsigned char*, char*,
+ unsigned int);
void reset_esms_by_digest();
=== modified file 'storage/perfschema/pfs_events_statements.h'
--- a/storage/perfschema/pfs_events_statements.h 2011-09-15 12:22:08 +0000
+++ b/storage/perfschema/pfs_events_statements.h 2011-10-04 12:16:34 +0000
@@ -30,14 +30,22 @@ struct PFS_user;
struct PFS_host;
/**
+ Structure to store a MD5 hash value (digest) for a statement.
+*/
+struct {
+ unsigned char m_md5[16];
+ }typedef PFS_digest_hash;
+
+/**
Structure to store token count/array for a statement
on which digest is to be calculated.
*/
#define PFS_MAX_TOKEN_COUNT 1024
-typedef struct {
+struct {
uint m_token_count;
uint m_token_array[PFS_MAX_TOKEN_COUNT];
- } PFS_digest_storage;
+ PFS_digest_hash m_digest_hash;
+ } typedef PFS_digest_storage;
/** A statement record. */
=== modified file 'storage/perfschema/table_esms_by_digest.cc'
--- a/storage/perfschema/table_esms_by_digest.cc 2011-09-13 11:29:39 +0000
+++ b/storage/perfschema/table_esms_by_digest.cc 2011-10-04 12:16:34 +0000
@@ -218,7 +218,11 @@ int table_esms_by_digest::rnd_next(void)
m_pos.set_at(&m_next_pos);
digest_stat= &statements_digest_stat_array[m_pos.m_index];
- if(digest_stat->m_digest[0] != '\0')
+ /*
+ If digest information exist for this record,
+ make a new row.
+ */
+ if(digest_stat->m_digest_text[0] != '\0')
{
make_row(digest_stat);
m_next_pos.set_after(&m_pos);
@@ -236,7 +240,11 @@ table_esms_by_digest::rnd_pos(const void
set_position(pos);
digest_stat= &statements_digest_stat_array[m_pos.m_index];
- if(digest_stat->m_digest[0] != '\0')
+ /*
+ If digest information exist for this record,
+ make a new row.
+ */
+ if(digest_stat->m_digest_text[0] != '\0')
{
make_row(digest_stat);
return 0;
@@ -250,6 +258,7 @@ void table_esms_by_digest::make_row(PFS_
{
m_row_exists= false;
m_row.m_digest.make_row(digest_stat);
+ /* TODO Add code for statements stats */
m_row_exists= true;
}
=== modified file 'storage/perfschema/table_helper.cc'
--- a/storage/perfschema/table_helper.cc 2011-09-13 11:29:39 +0000
+++ b/storage/perfschema/table_helper.cc 2011-10-04 12:16:34 +0000
@@ -103,11 +103,21 @@ void PFS_account_row::set_field(uint ind
int PFS_digest_row::make_row(PFS_statements_digest_stat* pfs)
{
- m_digest_length= pfs->m_digest_length;
- if (m_digest_length > sizeof(m_digest))
- return 1;
- if (m_digest_length > 0)
- memcpy(m_digest, pfs->m_digest, sizeof(m_digest));
+ /*
+ Write MD5 hash value in a string to be used as DIGEST for the statement.
+ */
+ sprintf(pfs->m_digest, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+ "%02x%02x%02x",
+ pfs->m_md5_hash.m_md5[0], pfs->m_md5_hash.m_md5[1], pfs->m_md5_hash.m_md5[2],
+ pfs->m_md5_hash.m_md5[3], pfs->m_md5_hash.m_md5[4], pfs->m_md5_hash.m_md5[5],
+ pfs->m_md5_hash.m_md5[6], pfs->m_md5_hash.m_md5[7], pfs->m_md5_hash.m_md5[8],
+ pfs->m_md5_hash.m_md5[9], pfs->m_md5_hash.m_md5[10], pfs->m_md5_hash.m_md5[11],
+ pfs->m_md5_hash.m_md5[12], pfs->m_md5_hash.m_md5[13], pfs->m_md5_hash.m_md5[14],
+ pfs->m_md5_hash.m_md5[15]);
+ pfs->m_digest_length= 16;
+
+ memcpy(m_digest, pfs->m_digest, sizeof(m_digest));
+ m_digest_length= 16;
m_digest_text_length= pfs->m_digest_text_length;
if (m_digest_text_length > sizeof(m_digest_text))
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk-wl5767 branch (mayank.prasad:3384 to 3385) WL#5767 | Mayank Prasad | 5 Oct |