Bug fix and improved debugging

For better debugging, added functions:
MySQL_Data_Stream::clean_net_failure()
MySQL_Data_Stream::set_net_failure()
MySQL_Data_Stream::setDSS_STATE_QUERY_SENT_NET()
MySQL_Session::set_unhealthy()

Added condition mybe->server_myds->PSarrayOUTpending->len==0 to determine if DSS can be STATE_QUERY_SENT_NET
pull/95/merge
René Cannaò 11 years ago
parent 01834ee2f3
commit 9cdebef9ca

@ -97,6 +97,10 @@ class MySQL_Data_Stream
void set_pollout();
void mysql_free();
void clean_net_failure();
void set_net_failure();
void setDSS_STATE_QUERY_SENT_NET();
int read_pkts();
int write_pkts();

@ -104,6 +104,7 @@ class MySQL_Session
// MySQL_Session(int);
~MySQL_Session();
void set_unhealthy();
//MySQL_Protocol myprot_client;
//MySQL_Protocol myprot_server;

@ -341,7 +341,7 @@ int MySQL_Session::handler() {
// server_myds=mybe->server_myds;
//}
mybe->server_myds->PSarrayOUT->add(pkt.ptr, pkt.size);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
} else {
// this is processed by the admin module
admin_func(this, GloAdmin, &pkt);
@ -535,6 +535,8 @@ __exit_DSS__STATE_NOT_INITIALIZED:
&&
mybe->server_myds->PSarrayOUT->len==0
&&
mybe->server_myds->PSarrayOUTpending->len==0
&&
mybe->server_myds->net_failure==false
&&
mybe->server_myds->available_data_out()==false
@ -542,11 +544,12 @@ __exit_DSS__STATE_NOT_INITIALIZED:
if (connections_handler) {
mybe->server_myds->DSS=STATE_PING_SENT_NET;
} else {
mybe->server_myds->DSS=STATE_QUERY_SENT_NET;
mybe->server_myds->setDSS_STATE_QUERY_SENT_NET();
}
}
if (mybe && mybe->server_myds) {
if (mybe->server_myds->net_failure) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p , MYDS:%p , myds_type=%d, DSS=%d , myconn:%p\n" , this, mybe->server_myds , mybe->server_myds->myds_type , mybe->server_myds->DSS, mybe->server_myds->myconn);
if (( mybe->server_myds->DSS==STATE_READY || mybe->server_myds->DSS==STATE_QUERY_SENT_DS ) && mybe->server_myds->myds_type==MYDS_BACKEND) {
mybe->server_myds->myconn=NULL;
mybe->server_myds->DSS=STATE_NOT_INITIALIZED;
@ -556,17 +559,18 @@ __exit_DSS__STATE_NOT_INITIALIZED:
mybe->server_myds->myconn=NULL;
}
if (mybe->server_myds->fd) {
shutdown(mybe->server_myds->fd,SHUT_RDWR);
close(mybe->server_myds->fd);
mybe->server_myds->shut_hard();
// shutdown(mybe->server_myds->fd,SHUT_RDWR);
// close(mybe->server_myds->fd);
mybe->server_myds->fd=0;
thread->mypolls.remove_index_fast(mybe->server_myds->poll_fds_idx);
//server_fd=0;
}
mybe->server_myds->net_failure=false;
mybe->server_myds->clean_net_failure();
mybe->server_myds->active=1;
goto __get_a_backend;
} else {
healthy=0;
set_unhealthy();
}
}
}
@ -606,7 +610,7 @@ bool MySQL_Session::handler___status_CHANGING_SCHEMA(PtrSize_t *pkt) {
return true;
} else {
l_free(pkt->size,pkt->ptr);
healthy=0;
set_unhealthy();
//mybe->myconn=server_myds->myconn;
// if we reach here, server_myds->DSS should be STATE_QUERY_SENT , therefore the connection to the backend should be dropped anyway
// although we enforce this here
@ -633,7 +637,7 @@ bool MySQL_Session::handler___status_CHANGING_USER_SERVER(PtrSize_t *pkt) {
return true;
} else {
l_free(pkt->size,pkt->ptr);
healthy=0;
set_unhealthy();
//mybe->myconn=server_myds->myconn;
// if we reach here, server_myds->DSS should be STATE_QUERY_SENT , therefore the connection to the backend should be dropped anyway
// although we enforce this here
@ -813,7 +817,7 @@ void MySQL_Session::handler___status_CONNECTING_SERVER___STATE_CLIENT_HANDSHAKE(
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Wrong credentials for backend: disconnecting\n");
l_free(pkt->size,pkt->ptr);
*wrong_pass=true;
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
char *_s=(char *)malloc(strlen(client_myds->myconn->userinfo->username)+100);
sprintf(_s,"Access denied for user '%s' (using password: %s)", client_myds->myconn->userinfo->username, (client_myds->myconn->userinfo->password ? "YES" : "NO"));
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000", _s);
@ -862,7 +866,7 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Wrong credentials for frontend: disconnecting\n");
*wrong_pass=true;
// FIXME: this should become close connection
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
char *_s=(char *)malloc(strlen(client_myds->myconn->userinfo->username)+100);
sprintf(_s,"Access denied for user '%s' (using password: %s)", client_myds->myconn->userinfo->username, (client_myds->myconn->userinfo->password ? "YES" : "NO"));
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,2,1045,(char *)"#28000", _s);
@ -896,7 +900,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
v=*((char *)pkt->ptr+3);
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_SET_OPTION packet , value %d\n", v);
// FIXME: ProxySQL doesn't support yet CLIENT_MULTI_STATEMENTS
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
if (v==1) {
client_myds->myprot.generate_pkt_EOF(true,NULL,NULL,1,0,0);
} else {
@ -909,7 +913,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PING(PtrSize_t *pkt) {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_PING packet\n");
l_free(pkt->size,pkt->ptr);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,2,0,NULL);
client_myds->DSS=STATE_SLEEP;
}
@ -918,12 +922,12 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if (admin==false) {
/* FIXME: temporary */
l_free(pkt->size,pkt->ptr);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported");
client_myds->DSS=STATE_SLEEP;
} else {
l_free(pkt->size,pkt->ptr);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported");
client_myds->DSS=STATE_SLEEP;
}
@ -965,7 +969,7 @@ __exit_from_debug:
l_free(query_length,query);
l_free(query_length,query_no_space);
l_free(pkt->size,pkt->ptr);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
if (result) {
// SQLite3_result * result = thread->SQL3_Thread_status(this);
SQLite3_to_MySQL(result,NULL,0,&client_myds->myprot);
@ -983,12 +987,12 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if (admin==false) {
client_myds->myconn->userinfo->set_schemaname((char *)pkt->ptr+sizeof(mysql_hdr)+1,pkt->size-sizeof(mysql_hdr)-1);
l_free(pkt->size,pkt->ptr);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,2,0,NULL);
client_myds->DSS=STATE_SLEEP;
} else {
l_free(pkt->size,pkt->ptr);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_OK(true,NULL,NULL,1,0,0,2,0,NULL);
client_myds->DSS=STATE_SLEEP;
}
@ -1027,7 +1031,7 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STATISTICS(PtrSize_t *pkt) {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_STATISTICS packet\n");
l_free(pkt->size,pkt->ptr);
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_statistics_response(true,NULL,NULL);
client_myds->DSS=STATE_SLEEP;
}
@ -1218,3 +1222,9 @@ SQLite3_result * MySQL_Session::SQL3_Session_status() {
free(pta);
return result;
}
void MySQL_Session::set_unhealthy() {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p\n", this);
healthy=0;
}

@ -728,6 +728,7 @@ virtual void run() {
while (shutdown==0) {
/*
int num_idles;
if (processing_idles==false && (last_processing_idles < curtime-5*1000000) ) {
int i;
@ -778,7 +779,7 @@ virtual void run() {
}
}
*/
for (n = 0; n < mypolls.len; n++) {
mypolls.fds[n].revents=0;
@ -870,7 +871,7 @@ virtual void run() {
// detected an error on backend
if ( (mypolls.fds[n].revents & POLLERR) || (mypolls.fds[n].revents & POLLHUP) ) {
// FIXME: try to handle it in a more graceful way
myds->sess->healthy=0;
myds->sess->set_unhealthy();
}
break;
default:
@ -896,7 +897,7 @@ void process_data_on_data_stream(MySQL_Data_Stream *myds, unsigned int n) {
&&
( (mypolls.fds[n].revents & POLLERR) || (mypolls.fds[n].revents & POLLHUP) )
) {
myds->net_failure=true;
myds->set_net_failure();
}
myds->check_data_flow();
@ -906,7 +907,7 @@ void process_data_on_data_stream(MySQL_Data_Stream *myds, unsigned int n) {
if (myds->active==FALSE) {
if (myds->sess->client_myds==myds) {
proxy_debug(PROXY_DEBUG_NET,1, "Session=%p, DataStream=%p -- Deleting FD %d\n", myds->sess, myds, myds->fd);
myds->sess->healthy=0;
myds->sess->set_unhealthy();
}
}

@ -142,6 +142,7 @@ MySQL_Connection::~MySQL_Connection() {
if (myds) {
myds->shut_hard();
} else {
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "MySQL_Connection %p , fd:%d\n", this, fd);
shutdown(fd, SHUT_RDWR);
close(fd);
}

@ -160,7 +160,7 @@ MySQL_Data_Stream::~MySQL_Data_Stream() {
if (mypolls) mypolls->remove_index_fast(poll_fds_idx);
if (fd>0) {
if (myconn==NULL || myconn->reusable==false) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "MySQL_Connection %p %s: shutdown socket\n", myconn, (myconn ? "not reusable" : "is empty"));
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p , MYDS:%p , MySQL_Connection %p %s: shutdown socket\n", sess, this, myconn, (myconn ? "not reusable" : "is empty"));
shut_hard();
// shutdown(fd,SHUT_RDWR);
// close(fd);
@ -203,14 +203,14 @@ void MySQL_Data_Stream::init(enum MySQL_DS_type _type, MySQL_Session *_sess, int
void MySQL_Data_Stream::shut_soft() {
proxy_debug(PROXY_DEBUG_NET, 4, "Shutdown soft fd=%d. Session=%p, DataStream=%p\n", fd, sess, this);
active=FALSE;
net_failure=true;
set_net_failure();
//if (sess) sess->net_failure=1;
}
// Hard shutdown of socket
void MySQL_Data_Stream::shut_hard() {
proxy_debug(PROXY_DEBUG_NET, 4, "Shutdown hard fd=%d. Session=%p, DataStream=%p\n", fd, sess, this);
net_failure=true;
set_net_failure();
if (fd >= 0) {
shutdown(fd, SHUT_RDWR);
close(fd);
@ -605,3 +605,23 @@ void MySQL_Data_Stream::unplug_backend() {
mypolls=NULL;
fd=0;
}
void MySQL_Data_Stream::clean_net_failure() {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p\n", this->sess, this);
net_failure=false;
}
void MySQL_Data_Stream::set_net_failure() {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p , myds_type:%d\n", this->sess, this, myds_type);
#ifdef DEBUG
if (myds_type!=MYDS_FRONTEND) {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p , myds_type:%d not frontend\n", this->sess, this, myds_type);
}
#endif /* DEBUG */
net_failure=true;
}
void MySQL_Data_Stream::setDSS_STATE_QUERY_SENT_NET() {
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p, myds=%p\n", this->sess, this);
DSS=STATE_QUERY_SENT_NET;
}

Loading…
Cancel
Save