From f31b10ff0e36958e355e4c0bd94deec025ba2f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Mon, 17 Aug 2015 08:29:46 +0000 Subject: [PATCH] Enhancements for issue #329 - added global variables mysql-query_digests - initialization if either mysql_thread___commands_stats or mysql_thread___query_digests are enabled - query_parser_free() checks if QueryParserArgs was initialized - Query_Processor::query_parser_init() checks the command type only if mysql_thread___commands_stats is true - Query_Processor::query_parser_init() run mysql_query_digest() only if mysql_thread___query_digests is true - Query_Processor::query_parser_update_counters() updates query digests only if digest_text is not null - start time is always update (this is relevant for issue #327) --- include/MySQL_Thread.h | 1 + include/proxysql_structs.h | 2 ++ lib/MySQL_Session.cpp | 11 +++++---- lib/MySQL_Thread.cpp | 18 +++++++++++++++ lib/Query_Processor.cpp | 47 ++++++++++++++++++++------------------ 5 files changed, 52 insertions(+), 27 deletions(-) diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h index 20dbe1fb3..ab891f31d 100644 --- a/include/MySQL_Thread.h +++ b/include/MySQL_Thread.h @@ -262,6 +262,7 @@ class MySQL_Threads_Handler uint8_t default_charset; bool servers_stats; bool commands_stats; + bool query_digests; bool default_reconnect; bool have_compress; int max_transaction_time; diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index a328b6ca5..0b0c70dbd 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -686,6 +686,7 @@ __thread int mysql_thread___poll_timeout_on_failure; __thread bool mysql_thread___have_compress; __thread bool mysql_thread___servers_stats; __thread bool mysql_thread___commands_stats; +__thread bool mysql_thread___query_digests; __thread bool mysql_thread___default_reconnect; __thread bool mysql_thread___sessions_sort; @@ -733,6 +734,7 @@ extern __thread int mysql_thread___poll_timeout_on_failure; extern __thread bool mysql_thread___have_compress; extern __thread bool mysql_thread___servers_stats; extern __thread bool mysql_thread___commands_stats; +extern __thread bool mysql_thread___query_digests; extern __thread bool mysql_thread___default_reconnect; extern __thread bool mysql_thread___sessions_sort; diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 9301e16e8..7ef3efd15 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -87,9 +87,9 @@ void Query_Info::begin(unsigned char *_p, int len, bool mysql_header) { QueryPointer=NULL; QueryLength=0; QueryParserArgs=NULL; - if (mysql_thread___commands_stats) { + start_time=sess->thread->curtime; + if (mysql_thread___commands_stats || mysql_thread___query_digests) { init(_p, len, mysql_header); - start_time=sess->thread->curtime; query_parser_init(); query_parser_command_type(); } @@ -106,7 +106,6 @@ void Query_Info::init(unsigned char *_p, int len, bool mysql_header) { QueryPointer=(unsigned char *)l_alloc(QueryLength+1); memcpy(QueryPointer,(mysql_header ? _p+5 : _p),QueryLength); QueryPointer[QueryLength]=0; - //QueryPointer=(mysql_header ? _p+5 : _p); QueryParserArgs=NULL; MyComQueryCmd=MYSQL_COM_QUERY_UNKNOWN; } @@ -121,8 +120,10 @@ enum MYSQL_COM_QUERY_command Query_Info::query_parser_command_type() { } void Query_Info::query_parser_free() { - GloQPro->query_parser_free(QueryParserArgs); - QueryParserArgs=NULL; + if (QueryParserArgs) { + GloQPro->query_parser_free(QueryParserArgs); + QueryParserArgs=NULL; + } } unsigned long long Query_Info::query_parser_update_counters() { diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp index 3ada15fa9..3e20e1514 100644 --- a/lib/MySQL_Thread.cpp +++ b/lib/MySQL_Thread.cpp @@ -168,6 +168,7 @@ static char * mysql_thread_variables_names[]= { (char *)"server_version", (char *)"sessions_sort", (char *)"commands_stats", + (char *)"query_digests", (char *)"servers_stats", (char *)"default_reconnect", (char *)"session_debug", @@ -226,6 +227,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() { variables.poll_timeout_on_failure=100; variables.have_compress=true; variables.commands_stats=true; + variables.query_digests=true; variables.sessions_sort=true; variables.servers_stats=true; variables.default_reconnect=true; @@ -359,6 +361,7 @@ int MySQL_Threads_Handler::get_variable_int(char *name) { if (!strcasecmp(name,"ping_timeout_server")) return (int)variables.ping_timeout_server; if (!strcasecmp(name,"have_compress")) return (int)variables.have_compress; if (!strcasecmp(name,"commands_stats")) return (int)variables.commands_stats; + if (!strcasecmp(name,"query_digests")) return (int)variables.commands_stats; if (!strcasecmp(name,"sessions_sort")) return (int)variables.sessions_sort; if (!strcasecmp(name,"servers_stats")) return (int)variables.servers_stats; if (!strcasecmp(name,"default_reconnect")) return (int)variables.default_reconnect; @@ -498,6 +501,9 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f if (!strcasecmp(name,"commands_stats")) { return strdup((variables.commands_stats ? "true" : "false")); } + if (!strcasecmp(name,"query_digests")) { + return strdup((variables.query_digests ? "true" : "false")); + } if (!strcasecmp(name,"sessions_sort")) { return strdup((variables.sessions_sort ? "true" : "false")); } @@ -869,6 +875,17 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t } return false; } + if (!strcasecmp(name,"query_digests")) { + if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) { + variables.query_digests=true; + return true; + } + if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) { + variables.query_digests=false; + return true; + } + return false; + } if (!strcasecmp(name,"sessions_sort")) { if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) { variables.sessions_sort=true; @@ -1501,6 +1518,7 @@ void MySQL_Thread::refresh_variables() { mysql_thread___poll_timeout_on_failure=GloMTH->get_variable_int((char *)"poll_timeout_on_failure"); mysql_thread___have_compress=(bool)GloMTH->get_variable_int((char *)"have_compress"); mysql_thread___commands_stats=(bool)GloMTH->get_variable_int((char *)"commands_stats"); + mysql_thread___query_digests=(bool)GloMTH->get_variable_int((char *)"query_digests"); mysql_thread___sessions_sort=(bool)GloMTH->get_variable_int((char *)"sessions_sort"); mysql_thread___servers_stats=(bool)GloMTH->get_variable_int((char *)"servers_stats"); mysql_thread___default_reconnect=(bool)GloMTH->get_variable_int((char *)"default_reconnect"); diff --git a/lib/Query_Processor.cpp b/lib/Query_Processor.cpp index 1d11ffd72..8ec1fc111 100644 --- a/lib/Query_Processor.cpp +++ b/lib/Query_Processor.cpp @@ -786,11 +786,13 @@ void Query_Processor::update_query_processor_stats() { void * Query_Processor::query_parser_init(char *query, int query_length, int flags) { SQP_par_t *qp=(SQP_par_t *)malloc(sizeof(SQP_par_t)); - libinjection_sqli_init(&qp->sf, query, query_length, FLAG_SQL_MYSQL); + if (mysql_thread___commands_stats) + libinjection_sqli_init(&qp->sf, query, query_length, FLAG_SQL_MYSQL); qp->digest_text=NULL; - qp->digest_text=mysql_query_digest(query, query_length); - qp->digest=SpookyHash::Hash64(qp->digest_text,strlen(qp->digest_text),0); - + if (mysql_thread___query_digests) { + qp->digest_text=mysql_query_digest(query, query_length); + qp->digest=SpookyHash::Hash64(qp->digest_text,strlen(qp->digest_text),0); + } return (void *)qp; }; @@ -806,24 +808,25 @@ unsigned long long Query_Processor::query_parser_update_counters(MySQL_Session * SQP_par_t *qp=(SQP_par_t *)p; - uint64_t hash2; - SpookyHash *myhash=new SpookyHash(); - myhash->Init(19,3); - assert(sess); - assert(sess->client_myds); - assert(sess->client_myds->myconn); - assert(sess->client_myds->myconn->userinfo); - MySQL_Connection_userinfo *ui=sess->client_myds->myconn->userinfo; - assert(ui->username); - assert(ui->schemaname); - myhash->Update(ui->username,strlen(ui->username)); - myhash->Update(&qp->digest,sizeof(qp->digest)); - myhash->Update(ui->schemaname,strlen(ui->schemaname)); - myhash->Final(&qp->digest_total,&hash2); - delete myhash; - - update_query_digest(qp, ui, t, sess->thread->curtime); - + if (qp->digest_text) { + // this code is executed only if digest_text is not NULL , that means mysql_thread___query_digests was true when the query started + uint64_t hash2; + SpookyHash *myhash=new SpookyHash(); + myhash->Init(19,3); + assert(sess); + assert(sess->client_myds); + assert(sess->client_myds->myconn); + assert(sess->client_myds->myconn->userinfo); + MySQL_Connection_userinfo *ui=sess->client_myds->myconn->userinfo; + assert(ui->username); + assert(ui->schemaname); + myhash->Update(ui->username,strlen(ui->username)); + myhash->Update(&qp->digest,sizeof(qp->digest)); + myhash->Update(ui->schemaname,strlen(ui->schemaname)); + myhash->Final(&qp->digest_total,&hash2); + delete myhash; + update_query_digest(qp, ui, t, sess->thread->curtime); + } return ret; }