From b2a57d238f1f61ac4f6ceba2caa3d79343fb7525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Sun, 23 Aug 2015 16:04:35 +0000 Subject: [PATCH] For #343: removed struct mysql_real_query in MySQL_Data_Stream and replaced with class MyDS_real_query to hold only the packet coming from client Bugfix in Query_Processor::delete_QP_out() : attempt to free unallocated qpo Removed commented code --- include/MySQL_Data_Stream.h | 35 ++++++++++++++++++++++---- lib/MySQL_Session.cpp | 50 ++++++------------------------------- lib/Query_Processor.cpp | 4 ++- lib/mysql_data_stream.cpp | 11 ++++---- 4 files changed, 47 insertions(+), 53 deletions(-) diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index b9d4d318f..c1fb3588c 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -31,7 +31,30 @@ typedef struct _mysql_data_buffer_t { } mysql_data_buffer_t; */ - +// this class avoid copying data +class MyDS_real_query { + public: + PtrSize_t pkt; // packet coming from the client + char *QueryPtr; // pointer to beginning of the query + unsigned int QuerySize; // size of the query + void init(PtrSize_t *_pkt) { + assert(QueryPtr==NULL); + assert(QuerySize==0); + assert(pkt.ptr==NULL); + assert(pkt.size==0); + pkt.ptr=_pkt->ptr; + pkt.size=_pkt->size; + QueryPtr=(char *)pkt.ptr+5; + QuerySize=pkt.size-5; + } + void end() { + l_free(pkt.size,pkt.ptr); + pkt.size=0; + QuerySize=0; + pkt.ptr=NULL; + QueryPtr=NULL; + } +}; class MySQL_Data_Stream { @@ -102,10 +125,12 @@ class MySQL_Data_Stream PtrSize_t multi_pkt; uint8_t pkt_sid; - struct { - char *ptr; - unsigned int size; - } mysql_real_query; +// struct { +// char *ptr; +// unsigned int size; +// } mysql_real_query; + + MyDS_real_query mysql_real_query; MySQL_Data_Stream(); ~MySQL_Data_Stream(); diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 60b4e0985..cd6c2cad6 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -424,34 +424,14 @@ __get_pkts_from_client: if (admin==false) { bool rc_break=false; if (session_fast_forward==false) { + // Note: CurrentQuery sees the query as sent by the client. + // shortly after, the packets it used to contain the query will be deallocated CurrentQuery.begin((unsigned char *)pkt.ptr,pkt.size,true); -// if (mysql_thread___commands_stats==true) { -// CurrentQuery.init((unsigned char *)pkt.ptr,pkt.size,true); -// CurrentQuery.start_time=thread->curtime; -// CurrentQuery.query_parser_init(); -// CurrentQuery.query_parser_command_type(); -// //client_myds->myprot.process_pkt_COM_QUERY((unsigned char *)pkt.ptr,pkt.size); -// } } rc_break=handler_special_queries(&pkt); if (rc_break==true) { break; } -/* - //if (strncmp((char *)"select @@version_comment limit 1",(char *)pkt.ptr+5,pkt.size-5)==0) { - if (pkt.size==SELECT_VERSION_COMMENT_LEN+5 && strncmp((char *)SELECT_VERSION_COMMENT,(char *)pkt.ptr+5,pkt.size-5)==0) { - PtrSize_t pkt_2; - pkt_2.size=PROXYSQL_VERSION_COMMENT_LEN; - pkt_2.ptr=l_alloc(pkt_2.size); - //memcpy(pkt_2.ptr,"\x01\x00\x00\x01\x01\x27\x00\x00\x02\x03\x64\x65\x66\x00\x00\x00\x11\x40\x40\x76\x65\x72\x73\x69\x6f\x6e\x5f\x63\x6f\x6d\x6d\x65\x6e\x74\x00\x0c\x21\x00\x18\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x05\x00\x00\x03\xfe\x00\x00\x02\x00\x0b\x00\x00\x04\x0a(ProxySQL)\x05\x00\x00\x05\xfe\x00\x00\x02\x00",pkt_2.size); - memcpy(pkt_2.ptr,PROXYSQL_VERSION_COMMENT,pkt_2.size); - status=WAITING_CLIENT_DATA; - client_myds->DSS=STATE_SLEEP; - client_myds->PSarrayOUT->add(pkt_2.ptr,pkt_2.size); - l_free(pkt.size,pkt.ptr); - break; - } -*/ qpo=GloQPro->process_mysql_query(this,pkt.ptr,pkt.size,false); if (qpo) { rc_break=handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_qpo(&pkt); @@ -472,29 +452,15 @@ __get_pkts_from_client: pause_until+=qpo->delay*1000; } } - //if (server_myds!=mybe->server_myds) { - // server_myds=mybe->server_myds; - //} -#ifdef EXPMARIA proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Received query to be processed with MariaDB Client library\n"); - mybe->server_myds->mysql_real_query.size=pkt.size-5; - mybe->server_myds->mysql_real_query.ptr=(char *)malloc(pkt.size-5); -// mybe->server_myds->wait_until=0; -// if (qpo) { -// if (qpo->timeout > 0) { -// mybe->server_myds->wait_until=thread->curtime+qpo->timeout*1000; -// } -// } + //mybe->server_myds->mysql_real_query.size=pkt.size-5; + //mybe->server_myds->mysql_real_query.ptr=(char *)l_alloc(mybe->server_myds->mysql_real_query.size); mybe->server_myds->killed_at=0; - //fprintf(stderr,"times: %llu, %llu\n", mybe->server_myds->wait_until, thread->curtime); - memcpy(mybe->server_myds->mysql_real_query.ptr,(char *)pkt.ptr+5,pkt.size-5); - l_free(pkt.size,pkt.ptr); -#else - mybe->server_myds->PSarrayOUT->add(pkt.ptr, pkt.size); -#endif /* EXPMARIA */ - + //memcpy(mybe->server_myds->mysql_real_query.ptr,(char *)pkt.ptr+5,pkt.size-5); + //l_free(pkt.size,pkt.ptr); + mybe->server_myds->mysql_real_query.init(&pkt); client_myds->setDSS_STATE_QUERY_SENT_NET(); } else { // this is processed by the admin module @@ -729,7 +695,7 @@ handler_again: mybe->server_myds->wait_until+=def_query_timeout*1000; } } - int rc=myconn->async_query(myds->revents, myds->mysql_real_query.ptr,myds->mysql_real_query.size); + int rc=myconn->async_query(myds->revents, myds->mysql_real_query.QueryPtr,myds->mysql_real_query.QuerySize); // if (myconn->async_state_machine==ASYNC_QUERY_END) { if (rc==0) { diff --git a/lib/Query_Processor.cpp b/lib/Query_Processor.cpp index e730a00c7..7c742d9be 100644 --- a/lib/Query_Processor.cpp +++ b/lib/Query_Processor.cpp @@ -751,7 +751,9 @@ __exit_process_mysql_query: // this function is called by mysql_session to free the result generated by process_mysql_query() void Query_Processor::delete_QP_out(Query_Processor_Output *o) { //l_free(sizeof(QP_out_t),o); - delete o; + if (o) { + delete o; + } }; void Query_Processor::update_query_processor_stats() { diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 1f08ab782..846ab35dc 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -97,8 +97,10 @@ MySQL_Data_Stream::MySQL_Data_Stream() { client_addr=NULL; sess=NULL; - mysql_real_query.ptr=NULL; - mysql_real_query.size=0; + mysql_real_query.pkt.ptr=NULL; + mysql_real_query.pkt.size=0; + mysql_real_query.QueryPtr=NULL; + mysql_real_query.QuerySize=0; connect_retries_on_failure=0; max_connect_time=0; @@ -917,8 +919,7 @@ void MySQL_Data_Stream::return_MySQL_Connection_To_Pool() { } void MySQL_Data_Stream::free_mysql_real_query() { - if (mysql_real_query.ptr) { - free(mysql_real_query.ptr); - mysql_real_query.ptr=NULL; + if (mysql_real_query.QueryPtr) { + mysql_real_query.end(); } }