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:
VilhoRaatikka
2014-03-14 13:25:37 +02:00
parent cb6a976555
commit a3f7eebdc9
8 changed files with 233 additions and 293 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{