Extended session command support to cover COM_CHANGE_USER, and COM_INIT_DB.
This implementation doesn't guarantee execution order between session commands and queries if other backend server lags behind in session command execution. In poll.c : moved processing of EPOLLERR and EPOLLHUP after processing of EPOLLIN and EPOLLOUT. This ensures that COM_QUIT messages are read and routed forward before signals arrive (from local client/backend).
This commit is contained in:
@ -283,6 +283,8 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
}
|
||||
|
||||
if (backend_protocol->state == MYSQL_AUTH_FAILED) {
|
||||
|
||||
spinlock_acquire(&dcb->delayqlock);
|
||||
/*<
|
||||
* vraa : errorHandle
|
||||
* check the delayq before the reply
|
||||
@ -295,10 +297,12 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
0,
|
||||
"Connection to backend lost.");
|
||||
// consume all the delay queue
|
||||
dcb->delayq = gwbuf_consume(
|
||||
while ((dcb->delayq = gwbuf_consume(
|
||||
dcb->delayq,
|
||||
gwbuf_length(dcb->delayq));
|
||||
GWBUF_LENGTH(dcb->delayq))) != NULL);
|
||||
}
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
|
||||
|
||||
while (session->state != SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
@ -347,7 +351,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
pthread_self(),
|
||||
dcb->fd,
|
||||
current_session->user)));
|
||||
|
||||
|
||||
/* check the delay queue and flush the data */
|
||||
if (dcb->delayq)
|
||||
{
|
||||
@ -802,12 +806,6 @@ static int backend_write_delayqueue(DCB *dcb)
|
||||
localq = dcb->delayq;
|
||||
dcb->delayq = NULL;
|
||||
|
||||
/*<
|
||||
* Now we set the last command received, from the delayed queue
|
||||
*/
|
||||
|
||||
// memcpy(&dcb->command, &localq->command, sizeof(dcb->command));
|
||||
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
rc = dcb_write(dcb, localq);
|
||||
|
||||
@ -856,8 +854,6 @@ static int gw_change_user(DCB *backend, SERVER *server, SESSION *in_session, GWB
|
||||
backend_protocol = backend->protocol;
|
||||
client_protocol = in_session->client->protocol;
|
||||
|
||||
// queue->command = ROUTER_CHANGE_SESSION;
|
||||
|
||||
// now get the user, after 4 bytes header and 1 byte command
|
||||
client_auth_packet += 5;
|
||||
strcpy(username, (char *)client_auth_packet);
|
||||
@ -899,30 +895,14 @@ static int gw_change_user(DCB *backend, SERVER *server, SESSION *in_session, GWB
|
||||
|
||||
rv = gw_send_change_user_to_backend(database, username, client_sha1, backend_protocol);
|
||||
|
||||
/*<
|
||||
* The current queue was not handled by func.write() in gw_send_change_user_to_backend()
|
||||
* We wrote a new gwbuf
|
||||
* Set backend command here!
|
||||
*/
|
||||
memcpy(&backend->command, &queue->command, sizeof(backend->command));
|
||||
|
||||
/*<
|
||||
* Now copy new data into user session
|
||||
*/
|
||||
strcpy(current_session->user, username);
|
||||
strcpy(current_session->db, database);
|
||||
memcpy(current_session->client_sha1, client_sha1, sizeof(current_session->client_sha1));
|
||||
}
|
||||
|
||||
// consume all the data received from client
|
||||
|
||||
spinlock_acquire(&backend->writeqlock);
|
||||
|
||||
len = gwbuf_length(queue);
|
||||
queue = gwbuf_consume(queue, len);
|
||||
|
||||
spinlock_release(&backend->writeqlock);
|
||||
|
||||
}
|
||||
gwbuf_free(queue);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1157,7 +1157,6 @@ static int gw_error_client_event(DCB *dcb) {
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
|
||||
router->closeSession(router_instance, rsession);
|
||||
}
|
||||
dcb_close(dcb);
|
||||
@ -1215,7 +1214,8 @@ gw_client_hangup_event(DCB *dcb)
|
||||
void* router_instance;
|
||||
void* rsession;
|
||||
int rc = 1;
|
||||
#if defined(SS_DEBUG)
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
MySQLProtocol* protocol = (MySQLProtocol *)dcb->protocol;
|
||||
if (dcb->state == DCB_STATE_POLLING ||
|
||||
dcb->state == DCB_STATE_NOPOLLING ||
|
||||
@ -1224,8 +1224,6 @@ gw_client_hangup_event(DCB *dcb)
|
||||
CHK_PROTOCOL(protocol);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CHK_DCB(dcb);
|
||||
|
||||
if (dcb->state != DCB_STATE_POLLING) {
|
||||
@ -1242,7 +1240,6 @@ gw_client_hangup_event(DCB *dcb)
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
|
||||
router->closeSession(router_instance, rsession);
|
||||
}
|
||||
|
||||
@ -1314,13 +1311,6 @@ static int route_by_statement(
|
||||
uint8_t* payload;
|
||||
static size_t len;
|
||||
|
||||
#if defined(SS_DEBUG)
|
||||
uint8_t router_capabilities;
|
||||
|
||||
router_capabilities = router->getCapabilities(router_instance, rsession);
|
||||
|
||||
ss_dassert(router_capabilities == RCAP_TYPE_STMT_INPUT);
|
||||
#endif
|
||||
do
|
||||
{
|
||||
stmtbuf = gw_MySQL_get_next_stmt(&readbuf);
|
||||
|
@ -181,7 +181,7 @@ int gw_read_backend_handshake(MySQLProtocol *conn) {
|
||||
conn->state = MYSQL_AUTH_SENT;
|
||||
|
||||
// consume all the data here
|
||||
head = gwbuf_consume(head, gwbuf_length(head));
|
||||
head = gwbuf_consume(head, GWBUF_LENGTH(head));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -337,7 +337,7 @@ int gw_receive_backend_auth(
|
||||
/*<
|
||||
* Remove data from buffer.
|
||||
*/
|
||||
head = gwbuf_consume(head, gwbuf_length(head));
|
||||
head = gwbuf_consume(head, GWBUF_LENGTH(head));
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
|
Reference in New Issue
Block a user