From 62a60b7d906d1e69c926d4818eeb590ded8edaee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 28 Oct 2016 00:34:37 +0000 Subject: [PATCH 1/5] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index da1463cde..f4b816d05 100644 --- a/.gitignore +++ b/.gitignore @@ -101,6 +101,8 @@ deps/pcre/pcre/ #protobuf deps/protobuf/protobuf-2.6.1/ +deps/sqlite3/sqlite-amalgamation-3150000/ + test/.vagrant .DS_Store proxysql-tests.ini From 98607ff7066449f7a83c86492a0fd29768d25399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Fri, 28 Oct 2016 16:36:25 +0000 Subject: [PATCH 2/5] Bugfix for #765 --- .../mariadb-client-library/libmariadb.c.patch | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/deps/mariadb-client-library/libmariadb.c.patch b/deps/mariadb-client-library/libmariadb.c.patch index 51adcf3e4..49134eaba 100644 --- a/deps/mariadb-client-library/libmariadb.c.patch +++ b/deps/mariadb-client-library/libmariadb.c.patch @@ -1,20 +1,7 @@ -@@ -2257,6 +2268,44 @@ - /* reset the connection in all active statements - todo: check stmt->mysql in mysql_stmt* functions ! */ - for (;li_stmt;li_stmt= li_stmt->next) -+ { -+ stmt= (MYSQL_STMT *)li_stmt->data; -+ stmt->mysql= NULL; -+ SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0); -+ } -+ mysql_close_memory(mysql); -+ mysql_close_options(mysql); -+ mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; -+ -+ /* Clear pointers for better safety */ -+ bzero((char*) &mysql->options,sizeof(mysql->options)); -+ mysql->net.vio= 0; -+ if (mysql->free_me) +@@ -2396,6 +2396,36 @@ + bzero((char*) &mysql->options,sizeof(mysql->options)); + mysql->net.vio= 0; + if (mysql->free_me) + my_free((gptr) mysql); + } + DBUG_VOID_RETURN; @@ -37,9 +24,14 @@ + end_server(mysql); + } + } -+ /* reset the connection in all active statements -+ todo: check stmt->mysql in mysql_stmt* functions ! */ -+ for (;li_stmt;li_stmt= li_stmt->next) - { - stmt= (MYSQL_STMT *)li_stmt->data; - stmt->mysql= NULL; ++ mysql_close_memory(mysql); ++ mysql_close_options(mysql); ++ mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; ++ ++ /* Clear pointers for better safety */ ++ bzero((char*) &mysql->options,sizeof(mysql->options)); ++ mysql->net.vio= 0; ++ if (mysql->free_me) + my_free(mysql); + } + DBUG_VOID_RETURN; From 8074e738edf1a9de282c4c304281ac39761a90bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Sat, 29 Oct 2016 00:25:57 +0000 Subject: [PATCH 3/5] Added support for STMT_SEND_LONG_DATA #764 --- include/MySQL_PreparedStatement.h | 20 +++++++++ include/MySQL_Session.h | 1 + lib/MySQL_PreparedStatement.cpp | 69 +++++++++++++++++++++++++++++++ lib/MySQL_Session.cpp | 34 ++++++++++++++- 4 files changed, 123 insertions(+), 1 deletion(-) diff --git a/include/MySQL_PreparedStatement.h b/include/MySQL_PreparedStatement.h index f9405ef79..784310495 100644 --- a/include/MySQL_PreparedStatement.h +++ b/include/MySQL_PreparedStatement.h @@ -96,6 +96,26 @@ class stmt_execute_metadata_t { } }; + +typedef struct _stmt_long_data_t { + uint32_t stmt_id; + uint16_t param_id; + void *data; + unsigned long size; +} stmt_long_data_t; + + +class StmtLongDataHandler { + private: + PtrArray *long_datas; + public: + StmtLongDataHandler(); + ~StmtLongDataHandler(); + unsigned int reset(uint32_t _stmt_id); + bool add(uint32_t _stmt_id, uint16_t _param_id, void *_data, unsigned long _size); + void *get(uint32_t _stmt_id, uint16_t _param_id, unsigned long **_size); +}; + // server side, metadata related to STMT_EXECUTE are stored in MYSQL_STMT itself // client side, they are stored in stmt_execute_metadata_t // MySQL_STMTs_meta maps stmt_execute_metadata_t with stmt_id diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index ac389de1c..4e586bd0c 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -151,6 +151,7 @@ class MySQL_Session bool started_sending_data_to_client; // this status variable tracks if some result set was sent to the client, of if proysql is still buffering everything MySQL_STMTs_meta *sess_STMTs_meta; + StmtLongDataHandler *SLDH; MySQL_Session(); // MySQL_Session(int); diff --git a/lib/MySQL_PreparedStatement.cpp b/lib/MySQL_PreparedStatement.cpp index ac8859d80..31e45397a 100644 --- a/lib/MySQL_PreparedStatement.cpp +++ b/lib/MySQL_PreparedStatement.cpp @@ -394,3 +394,72 @@ MySQL_STMT_Global_info::~MySQL_STMT_Global_info() { digest_text=NULL; } } + +StmtLongDataHandler::StmtLongDataHandler() { + long_datas=new PtrArray(); +} + +StmtLongDataHandler::~StmtLongDataHandler() { + while (long_datas->len) { + stmt_long_data_t *sld=(stmt_long_data_t *)long_datas->remove_index_fast(0); + free(sld->data); + free(sld); + } + delete long_datas; +} + +bool StmtLongDataHandler::add(uint32_t _stmt_id, uint16_t _param_id, void *_data, unsigned long _size) { + stmt_long_data_t *sld=NULL; + unsigned int i; + for (i=0; ilen; i++) { + sld=(stmt_long_data_t *)long_datas->index(i); + if (sld->stmt_id==_stmt_id && sld->param_id==_param_id) { + // we found it! + unsigned long _new_size=sld->size + _size; + sld->data=realloc(sld->data, _new_size); + memcpy((unsigned char *)sld->data+sld->size, _data, _size); + sld->size=_new_size; + return true; + } + } + // if we reached here, we didn't find it + sld=(stmt_long_data_t *)malloc(sizeof(stmt_long_data_t)); + sld->stmt_id=_stmt_id; + sld->param_id=_param_id; + sld->size=_size; + sld->data=malloc(_size); + memcpy(sld->data,_data,_size); + long_datas->add(sld); + return false; // a new entry was created +} + +unsigned int StmtLongDataHandler::reset(uint32_t _stmt_id) { + unsigned int cnt=0; + int i; + stmt_long_data_t *sld=NULL; + for (i=0; i < (int)long_datas->len; i++) { // we treat it as an int, so we can go to -1 + sld=(stmt_long_data_t *)long_datas->index(i); + if (sld->stmt_id==_stmt_id) { + sld=(stmt_long_data_t *)long_datas->remove_index_fast(i); + free(sld->data); + free(sld); + i--; + cnt++; + } + } + return cnt; +} + +void * StmtLongDataHandler::get(uint32_t _stmt_id, uint16_t _param_id, unsigned long **_size) { + stmt_long_data_t *sld=NULL; + unsigned int i; + for (i=0; ilen; i++) { + sld=(stmt_long_data_t *)long_datas->index(i); + if (sld->stmt_id==_stmt_id && sld->param_id==_param_id) { + // we found it! + *_size=&sld->size; + return sld->data; + } + } + return NULL; +} diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 931e01ab3..f525b53e5 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -252,12 +252,14 @@ MySQL_Session::MySQL_Session() { transaction_persistent=false; active_transactions=0; sess_STMTs_meta=new MySQL_STMTs_meta(); + SLDH=new StmtLongDataHandler(); } MySQL_Session::~MySQL_Session() { if (sess_STMTs_meta) { delete sess_STMTs_meta; } + delete SLDH; if (client_myds) { if (client_authenticated) { GloMyAuth->decrease_frontend_user_connections(client_myds->myconn->userinfo->username); @@ -1533,8 +1535,11 @@ __get_pkts_from_client: case _MYSQL_COM_CHANGE_USER: handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_CHANGE_USER(&pkt, &wrong_pass); break; - case _MYSQL_COM_STMT_RESET: // FIXME: not really implemented yet + case _MYSQL_COM_STMT_RESET: { + uint32_t stmt_global_id=0; + memcpy(&stmt_global_id,(char *)pkt.ptr+5,sizeof(uint32_t)); + SLDH->reset(stmt_global_id); l_free(pkt.size,pkt.ptr); client_myds->setDSS_STATE_QUERY_SENT_NET(); unsigned int nTrx=NumActiveTransactions(); @@ -1550,6 +1555,7 @@ __get_pkts_from_client: uint32_t stmt_global_id=0; memcpy(&stmt_global_id,(char *)pkt.ptr+5,sizeof(uint32_t)); // FIXME: no input validation + SLDH->reset(stmt_global_id); sess_STMTs_meta->erase(stmt_global_id); client_myds->myconn->local_stmts->erase(stmt_global_id); } @@ -1562,6 +1568,19 @@ __get_pkts_from_client: client_myds->DSS=STATE_SLEEP; status=WAITING_CLIENT_DATA; break; + case _MYSQL_COM_STMT_SEND_LONG_DATA: + { + // FIXME: no input validation + uint32_t stmt_global_id=0; + memcpy(&stmt_global_id,(char *)pkt.ptr+5,sizeof(uint32_t)); + uint32_t stmt_param_id=0; + memcpy(&stmt_param_id,(char *)pkt.ptr+9,sizeof(uint16_t)); + SLDH->add(stmt_global_id,stmt_param_id,(char *)pkt.ptr+11,pkt.size-11); + } + client_myds->DSS=STATE_SLEEP; + status=WAITING_CLIENT_DATA; + l_free(pkt.size,pkt.ptr); + break; case _MYSQL_COM_STMT_PREPARE: if (admin==true) { // admin module will not support prepared statement!! l_free(pkt.size,pkt.ptr); @@ -1689,6 +1708,16 @@ __get_pkts_from_client: stmt_info=NULL; break; } + // handle cases in which data was sent via STMT_SEND_LONG_DATA + for (uint16_t ii=0; iinum_params; ii++) { + void *_data=NULL; + unsigned long *_l=0; + _data=SLDH->get(stmt_global_id,ii,&_l); + if (_data) { // data was sent via STMT_SEND_LONG_DATA + stmt_meta->binds[ii].length=_l; + stmt_meta->binds[ii].buffer=_data; + } + } if (stmt_meta_found==false) { // previously we didn't find any metadata // but as we reached here, stmt_meta is not null and we save the metadata @@ -2049,6 +2078,9 @@ handler_again: MySQL_Stmt_Result_to_MySQL_wire(CurrentQuery.mysql_stmt, myds->myconn); if (CurrentQuery.stmt_meta) if (CurrentQuery.stmt_meta->pkt) { + uint32_t stmt_global_id=0; + memcpy(&stmt_global_id,(char *)(CurrentQuery.stmt_meta->pkt)+5,sizeof(uint32_t)); + SLDH->reset(stmt_global_id); free(CurrentQuery.stmt_meta->pkt); CurrentQuery.stmt_meta->pkt=NULL; } From cd1f2def4df4ab834233e46459c7b1435c9a2d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Sat, 29 Oct 2016 11:09:52 +0000 Subject: [PATCH 4/5] Introducing custom error codes , see #761 --- lib/MySQL_Session.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index f525b53e5..bcd82d088 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1026,7 +1026,7 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) { } char buf[256]; sprintf(buf,"Max connect timeout reached while reaching hostgroup %d after %llums", current_hostgroup, (thread->curtime - CurrentQuery.start_time)/1000 ); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",buf); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,9001,(char *)"HY000",buf); // CurrentQuery.end(); // mybe->server_myds->free_mysql_real_query(); // client_myds->DSS=STATE_SLEEP; @@ -1131,7 +1131,7 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) { } else { char buf[256]; sprintf(buf,"Max connect failure while reaching hostgroup %d", current_hostgroup); - client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",buf); + client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,9002,(char *)"HY000",buf); } // CurrentQuery.end(); // myds->free_mysql_real_query(); From 0e8a99c303d5639f69c69fbc6fec746ba956f280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Sat, 29 Oct 2016 13:29:31 +0000 Subject: [PATCH 5/5] Preparation for 1.3.0f --- Makefile | 2 +- docker/images/proxysql/centos67-build/proxysql.spec | 2 +- docker/images/proxysql/centos7-build/proxysql.spec | 2 +- docker/images/proxysql/debian-7.8-build/proxysql.ctl | 2 +- docker/images/proxysql/debian-8.2-build/proxysql.ctl | 2 +- docker/images/proxysql/fedora24-build/proxysql.spec | 2 +- docker/images/proxysql/ubuntu-12.04-build/proxysql.ctl | 2 +- docker/images/proxysql/ubuntu-14.04-build/proxysql.ctl | 2 +- docker/images/proxysql/ubuntu-16.04-build/proxysql.ctl | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index fb4543f76..1aa28ce41 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ DEBUG=${ALL_DEBUG} #export DEBUG #export OPTZ #export EXTRALINK -CURVER=1.3.0e +CURVER=1.3.0f MAKEOPT="-j 8" DISTRO := $(shell gawk -F= '/^NAME/{print $$2}' /etc/os-release) ifeq ($(wildcard /usr/lib/systemd/systemd), /usr/lib/systemd/systemd) diff --git a/docker/images/proxysql/centos67-build/proxysql.spec b/docker/images/proxysql/centos67-build/proxysql.spec index b681977fa..8824da08e 100644 --- a/docker/images/proxysql/centos67-build/proxysql.spec +++ b/docker/images/proxysql/centos67-build/proxysql.spec @@ -7,7 +7,7 @@ Summary: A high-performance MySQL proxy Name: proxysql -Version: 1.3.0e +Version: 1.3.0f Release: 1 License: GPL+ Group: Development/Tools diff --git a/docker/images/proxysql/centos7-build/proxysql.spec b/docker/images/proxysql/centos7-build/proxysql.spec index b681977fa..8824da08e 100644 --- a/docker/images/proxysql/centos7-build/proxysql.spec +++ b/docker/images/proxysql/centos7-build/proxysql.spec @@ -7,7 +7,7 @@ Summary: A high-performance MySQL proxy Name: proxysql -Version: 1.3.0e +Version: 1.3.0f Release: 1 License: GPL+ Group: Development/Tools diff --git a/docker/images/proxysql/debian-7.8-build/proxysql.ctl b/docker/images/proxysql/debian-7.8-build/proxysql.ctl index 9cec6bb51..08519c7c6 100644 --- a/docker/images/proxysql/debian-7.8-build/proxysql.ctl +++ b/docker/images/proxysql/debian-7.8-build/proxysql.ctl @@ -4,7 +4,7 @@ Homepage: http://www.proxysql.com Standards-Version: 3.9.2 Package: proxysql -Version: 1.3.0e +Version: 1.3.0f Maintainer: Rene Cannao Architecture: amd64 # Changelog: CHANGELOG.md diff --git a/docker/images/proxysql/debian-8.2-build/proxysql.ctl b/docker/images/proxysql/debian-8.2-build/proxysql.ctl index 9cec6bb51..08519c7c6 100644 --- a/docker/images/proxysql/debian-8.2-build/proxysql.ctl +++ b/docker/images/proxysql/debian-8.2-build/proxysql.ctl @@ -4,7 +4,7 @@ Homepage: http://www.proxysql.com Standards-Version: 3.9.2 Package: proxysql -Version: 1.3.0e +Version: 1.3.0f Maintainer: Rene Cannao Architecture: amd64 # Changelog: CHANGELOG.md diff --git a/docker/images/proxysql/fedora24-build/proxysql.spec b/docker/images/proxysql/fedora24-build/proxysql.spec index b681977fa..8824da08e 100644 --- a/docker/images/proxysql/fedora24-build/proxysql.spec +++ b/docker/images/proxysql/fedora24-build/proxysql.spec @@ -7,7 +7,7 @@ Summary: A high-performance MySQL proxy Name: proxysql -Version: 1.3.0e +Version: 1.3.0f Release: 1 License: GPL+ Group: Development/Tools diff --git a/docker/images/proxysql/ubuntu-12.04-build/proxysql.ctl b/docker/images/proxysql/ubuntu-12.04-build/proxysql.ctl index 9cec6bb51..08519c7c6 100644 --- a/docker/images/proxysql/ubuntu-12.04-build/proxysql.ctl +++ b/docker/images/proxysql/ubuntu-12.04-build/proxysql.ctl @@ -4,7 +4,7 @@ Homepage: http://www.proxysql.com Standards-Version: 3.9.2 Package: proxysql -Version: 1.3.0e +Version: 1.3.0f Maintainer: Rene Cannao Architecture: amd64 # Changelog: CHANGELOG.md diff --git a/docker/images/proxysql/ubuntu-14.04-build/proxysql.ctl b/docker/images/proxysql/ubuntu-14.04-build/proxysql.ctl index 9cec6bb51..08519c7c6 100644 --- a/docker/images/proxysql/ubuntu-14.04-build/proxysql.ctl +++ b/docker/images/proxysql/ubuntu-14.04-build/proxysql.ctl @@ -4,7 +4,7 @@ Homepage: http://www.proxysql.com Standards-Version: 3.9.2 Package: proxysql -Version: 1.3.0e +Version: 1.3.0f Maintainer: Rene Cannao Architecture: amd64 # Changelog: CHANGELOG.md diff --git a/docker/images/proxysql/ubuntu-16.04-build/proxysql.ctl b/docker/images/proxysql/ubuntu-16.04-build/proxysql.ctl index 9cec6bb51..08519c7c6 100644 --- a/docker/images/proxysql/ubuntu-16.04-build/proxysql.ctl +++ b/docker/images/proxysql/ubuntu-16.04-build/proxysql.ctl @@ -4,7 +4,7 @@ Homepage: http://www.proxysql.com Standards-Version: 3.9.2 Package: proxysql -Version: 1.3.0e +Version: 1.3.0f Maintainer: Rene Cannao Architecture: amd64 # Changelog: CHANGELOG.md