Fixed queries being routed when the session is already closing.
This commit is contained in:
@ -197,6 +197,7 @@ GWBUF *rval;
|
|||||||
rval->gwbuf_info = buf->gwbuf_info;
|
rval->gwbuf_info = buf->gwbuf_info;
|
||||||
rval->gwbuf_bufobj = buf->gwbuf_bufobj;
|
rval->gwbuf_bufobj = buf->gwbuf_bufobj;
|
||||||
rval->tail = rval;
|
rval->tail = rval;
|
||||||
|
rval->next = NULL;
|
||||||
CHK_GWBUF(rval);
|
CHK_GWBUF(rval);
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
@ -1080,7 +1080,7 @@ gw_backend_hangup(DCB *dcb)
|
|||||||
len = sizeof(error);
|
len = sizeof(error);
|
||||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0)
|
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0)
|
||||||
{
|
{
|
||||||
if (error != 0)
|
if (error != 0 && ses_state != SESSION_STATE_STOPPING)
|
||||||
{
|
{
|
||||||
strerror_r(error, buf, 100);
|
strerror_r(error, buf, 100);
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
@ -1094,9 +1094,12 @@ gw_backend_hangup(DCB *dcb)
|
|||||||
goto retblock;
|
goto retblock;
|
||||||
}
|
}
|
||||||
#if defined(SS_DEBUG)
|
#if defined(SS_DEBUG)
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
if(ses_state != SESSION_STATE_STOPPING)
|
||||||
LOGFILE_ERROR,
|
{
|
||||||
"Backend hangup error handling.")));
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Backend hangup error handling.")));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
router->handleError(router_instance,
|
router->handleError(router_instance,
|
||||||
|
@ -1092,6 +1092,7 @@ int gw_read_client_event(
|
|||||||
case MYSQL_IDLE:
|
case MYSQL_IDLE:
|
||||||
{
|
{
|
||||||
uint8_t* payload = NULL;
|
uint8_t* payload = NULL;
|
||||||
|
session_state_t ses_state;
|
||||||
|
|
||||||
session = dcb->session;
|
session = dcb->session;
|
||||||
ss_dassert(session!= NULL);
|
ss_dassert(session!= NULL);
|
||||||
@ -1100,93 +1101,106 @@ int gw_read_client_event(
|
|||||||
{
|
{
|
||||||
CHK_SESSION(session);
|
CHK_SESSION(session);
|
||||||
}
|
}
|
||||||
|
spinlock_acquire(&session->ses_lock);
|
||||||
|
ses_state = session->state;
|
||||||
|
spinlock_release(&session->ses_lock);
|
||||||
/* Now, we are assuming in the first buffer there is
|
/* Now, we are assuming in the first buffer there is
|
||||||
* the information form mysql command */
|
* the information form mysql command */
|
||||||
payload = GWBUF_DATA(read_buffer);
|
payload = GWBUF_DATA(read_buffer);
|
||||||
|
|
||||||
/** Route COM_QUIT to backend */
|
if(ses_state == SESSION_STATE_ROUTER_READY)
|
||||||
if (MYSQL_IS_COM_QUIT(payload))
|
{
|
||||||
{
|
/** Route COM_QUIT to backend */
|
||||||
|
if (MYSQL_IS_COM_QUIT(payload))
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Sends COM_QUIT packets since buffer is already
|
* Sends COM_QUIT packets since buffer is already
|
||||||
* created. A BREF_CLOSED flag is set so dcb_close won't
|
* created. A BREF_CLOSED flag is set so dcb_close won't
|
||||||
* send redundant COM_QUIT.
|
* send redundant COM_QUIT.
|
||||||
*/
|
*/
|
||||||
SESSION_ROUTE_QUERY(session, read_buffer);
|
SESSION_ROUTE_QUERY(session, read_buffer);
|
||||||
/**
|
/**
|
||||||
* Close router session which causes closing of backends.
|
* Close router session which causes closing of backends.
|
||||||
*/
|
*/
|
||||||
dcb_close(dcb);
|
dcb_close(dcb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/** Reset error handler when routing of the new query begins */
|
/** Reset error handler when routing of the new query begins */
|
||||||
router->handleError(NULL, NULL, NULL, dcb, ERRACT_RESET, NULL);
|
router->handleError(NULL, NULL, NULL, dcb, ERRACT_RESET, NULL);
|
||||||
|
|
||||||
if (stmt_input)
|
if (stmt_input)
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Feed each statement completely and separately
|
* Feed each statement completely and separately
|
||||||
* to router.
|
* to router.
|
||||||
*/
|
*/
|
||||||
rc = route_by_statement(session, &read_buffer);
|
rc = route_by_statement(session, &read_buffer);
|
||||||
|
|
||||||
if (read_buffer != NULL)
|
if (read_buffer != NULL)
|
||||||
{
|
{
|
||||||
/** add incomplete mysql packet to read queue */
|
/** add incomplete mysql packet to read queue */
|
||||||
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/** Feed whole packet to router */
|
/** Feed whole packet to router */
|
||||||
rc = SESSION_ROUTE_QUERY(session, read_buffer);
|
rc = SESSION_ROUTE_QUERY(session, read_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Routing succeed */
|
/** Routing succeed */
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
rc = 0; /**< here '0' means success */
|
rc = 0; /**< here '0' means success */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool succp;
|
bool succp;
|
||||||
GWBUF* errbuf;
|
GWBUF* errbuf;
|
||||||
/**
|
/**
|
||||||
* Create error to be sent to client if session
|
* Create error to be sent to client if session
|
||||||
* can't be continued.
|
* can't be continued.
|
||||||
*/
|
*/
|
||||||
errbuf = mysql_create_custom_error(
|
errbuf = mysql_create_custom_error(
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
"Routing failed. Session is closed.");
|
"Routing failed. Session is closed.");
|
||||||
/**
|
/**
|
||||||
* Ensure that there are enough backends
|
* Ensure that there are enough backends
|
||||||
* available.
|
* available.
|
||||||
*/
|
*/
|
||||||
router->handleError(
|
router->handleError(
|
||||||
router_instance,
|
router_instance,
|
||||||
session->router_session,
|
session->router_session,
|
||||||
errbuf,
|
errbuf,
|
||||||
dcb,
|
dcb,
|
||||||
ERRACT_NEW_CONNECTION,
|
ERRACT_NEW_CONNECTION,
|
||||||
&succp);
|
&succp);
|
||||||
gwbuf_free(errbuf);
|
gwbuf_free(errbuf);
|
||||||
/**
|
/**
|
||||||
* If there are not enough backends close
|
* If there are not enough backends close
|
||||||
* session
|
* session
|
||||||
*/
|
*/
|
||||||
if (!succp)
|
if (!succp)
|
||||||
{
|
{
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Routing the query failed. "
|
"Error : Routing the query failed. "
|
||||||
"Session will be closed.")));
|
"Session will be closed.")));
|
||||||
|
|
||||||
dcb_close(dcb);
|
dcb_close(dcb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skygw_log_write_flush(LT,"Session received a query in state %s",
|
||||||
|
STRSESSIONSTATE(ses_state));
|
||||||
|
while((read_buffer = GWBUF_CONSUME_ALL(read_buffer)) != NULL);
|
||||||
|
goto return_rc;
|
||||||
|
}
|
||||||
goto return_rc;
|
goto return_rc;
|
||||||
} /* MYSQL_IDLE */
|
} /* MYSQL_IDLE */
|
||||||
break;
|
break;
|
||||||
|
@ -723,16 +723,10 @@ routeQuery(ROUTER *instance, void *router_session, GWBUF *queue)
|
|||||||
SERVER_IS_DOWN(router_cli_ses->backend->server))
|
SERVER_IS_DOWN(router_cli_ses->backend->server))
|
||||||
{
|
{
|
||||||
LOGIF(LT, (skygw_log_write(
|
LOGIF(LT, (skygw_log_write(
|
||||||
LOGFILE_TRACE,
|
LOGFILE_TRACE|LOGFILE_ERROR,
|
||||||
"Error : Failed to route MySQL command %d to backend "
|
"Error : Failed to route MySQL command %d to backend "
|
||||||
"server.",
|
"server.%s",
|
||||||
mysql_command)));
|
mysql_command,rses_is_closed ? " Session is closed." : "")));
|
||||||
skygw_log_write(
|
|
||||||
LOGFILE_ERROR,
|
|
||||||
"Error : Failed to route MySQL command %d to backend "
|
|
||||||
"server %s.",
|
|
||||||
mysql_command,
|
|
||||||
router_cli_ses->backend->server->unique_name);
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
goto return_rc;
|
goto return_rc;
|
||||||
|
|
||||||
|
@ -3915,7 +3915,7 @@ static GWBUF* sescmd_cursor_clone_querybuf(
|
|||||||
}
|
}
|
||||||
ss_dassert(scur->scmd_cur_cmd != NULL);
|
ss_dassert(scur->scmd_cur_cmd != NULL);
|
||||||
|
|
||||||
buf = gwbuf_clone(scur->scmd_cur_cmd->my_sescmd_buf);
|
buf = gwbuf_clone_all(scur->scmd_cur_cmd->my_sescmd_buf);
|
||||||
|
|
||||||
CHK_GWBUF(buf);
|
CHK_GWBUF(buf);
|
||||||
return buf;
|
return buf;
|
||||||
|
Reference in New Issue
Block a user