ReadConnRoute can handle now COM_CHANGE_USER
mysql_backend calls routeReply with backand results. routeReply in readwritesplit.c can understand the dcb->command value
This commit is contained in:
@ -42,14 +42,16 @@
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 14/06/13 Mark Riddoch Initial implementation
|
||||
* 25/06/13 Mark Riddoch Addition of checks for current server state
|
||||
* 26/06/13 Mark Riddoch Use server with least connections since
|
||||
* startup if the number of current
|
||||
* connections is the same for two servers
|
||||
* Addition of master and slave options
|
||||
* 27/06/13 Vilho Raatikka Added skygw_log_write command as an example
|
||||
* and necessary headers.
|
||||
* 14/06/2013 Mark Riddoch Initial implementation
|
||||
* 25/06/2013 Mark Riddoch Addition of checks for current server state
|
||||
* 26/06/2013 Mark Riddoch Use server with least connections since
|
||||
* startup if the number of current
|
||||
* connections is the same for two servers
|
||||
* Addition of master and slave options
|
||||
* 27/06/2013 Vilho Raatikka Added skygw_log_write command as an example
|
||||
* and necessary headers.
|
||||
* 17/07/2013 Massimiliano Pinto Added clientReply routine:
|
||||
called by backend server to send data to client
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -77,9 +79,10 @@ static void *newSession(ROUTER *instance, SESSION *session);
|
||||
static void closeSession(ROUTER *instance, void *router_session);
|
||||
static int routeQuery(ROUTER *instance, void *router_session, GWBUF *queue);
|
||||
static void diagnostics(ROUTER *instance, DCB *dcb);
|
||||
static void clientReply(ROUTER* instance, void* router_session, GWBUF* queue, DCB *backend_dcb);
|
||||
|
||||
/** The module object definition */
|
||||
static ROUTER_OBJECT MyObject = { createInstance, newSession, closeSession, routeQuery, diagnostics, NULL };
|
||||
static ROUTER_OBJECT MyObject = { createInstance, newSession, closeSession, routeQuery, diagnostics, clientReply };
|
||||
|
||||
static SPINLOCK instlock;
|
||||
static INSTANCE *instances;
|
||||
@ -369,9 +372,18 @@ routeQuery(ROUTER *instance, void *router_session, GWBUF *queue)
|
||||
{
|
||||
INSTANCE *inst = (INSTANCE *)instance;
|
||||
CLIENT_SESSION *session = (CLIENT_SESSION *)router_session;
|
||||
char *paylod = GWBUF_DATA(queue);
|
||||
int mysql_command = -1;
|
||||
|
||||
mysql_command = paylod[4];
|
||||
|
||||
inst->stats.n_queries++;
|
||||
return session->dcb->func.write(session->dcb, queue);
|
||||
|
||||
if (mysql_command == 0x11) {
|
||||
return session->dcb->func.auth(session->dcb, NULL, session->dcb->session, queue);
|
||||
} else {
|
||||
return session->dcb->func.write(session->dcb, queue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,3 +412,29 @@ int i = 0;
|
||||
dcb_printf(dcb, "\tCurrent no. of router sessions: %d\n", i);
|
||||
dcb_printf(dcb, "\tNumber of queries forwarded: %d\n", inst->stats.n_queries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client Reply routine
|
||||
*
|
||||
* The routine will reply to client data from backend server
|
||||
*
|
||||
* @param instance The router instance
|
||||
* @param router_session The router session
|
||||
* @param backend_dcb The backend DCB
|
||||
* @param queue The GWBUF with reply data
|
||||
*/
|
||||
static void
|
||||
clientReply(ROUTER* instance, void* router_session, GWBUF* queue, DCB *backend_dcb)
|
||||
{
|
||||
INSTANCE* inst = NULL;
|
||||
DCB *client = NULL;
|
||||
CLIENT_SESSION* session = NULL;
|
||||
|
||||
inst = (INSTANCE *)instance;
|
||||
session = (CLIENT_SESSION *)router_session;
|
||||
|
||||
client = backend_dcb->session->client;
|
||||
|
||||
client->func.write(client, queue);
|
||||
}
|
||||
///
|
||||
|
@ -23,8 +23,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <mysql.h>
|
||||
#if defined(SS_DEBUG)
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
#endif
|
||||
#include <query_classifier.h>
|
||||
#include <dcb.h>
|
||||
#include <spinlock.h>
|
||||
@ -420,28 +422,35 @@ static int routeQuery(
|
||||
case COM_DAEMON: /**< 1d ? */
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(SS_DEBUG_)
|
||||
skygw_log_write(NULL, LOGFILE_TRACE, "String\t\"%s\"", querystr);
|
||||
skygw_log_write(NULL,
|
||||
LOGFILE_TRACE,
|
||||
"Packet type\t%s",
|
||||
STRPACKETTYPE(packet_type));
|
||||
|
||||
#endif
|
||||
|
||||
switch (qtype) {
|
||||
case QUERY_TYPE_WRITE:
|
||||
#if defined(SS_DEBUG_)
|
||||
skygw_log_write(NULL,
|
||||
LOGFILE_TRACE,
|
||||
"Query type\t%s, routing to Master.",
|
||||
STRQTYPE(qtype));
|
||||
#endif
|
||||
ret = session->masterconn->func.write(session->masterconn, queue);
|
||||
atomic_add(&inst->stats.n_master, 1);
|
||||
goto return_ret;
|
||||
break;
|
||||
|
||||
case QUERY_TYPE_READ:
|
||||
#if defined(SS_DEBUG_)
|
||||
skygw_log_write(NULL,
|
||||
LOGFILE_TRACE,
|
||||
"Query type\t%s, routing to Slave.",
|
||||
STRQTYPE(qtype));
|
||||
#endif
|
||||
ret = session->slaveconn->func.write(session->slaveconn, queue);
|
||||
atomic_add(&inst->stats.n_slave, 1);
|
||||
goto return_ret;
|
||||
@ -449,10 +458,12 @@ static int routeQuery(
|
||||
|
||||
|
||||
case QUERY_TYPE_SESSION_WRITE:
|
||||
#if defined(SS_DEBUG_)
|
||||
skygw_log_write(NULL,
|
||||
LOGFILE_TRACE,
|
||||
"Query type\t%s, routing to All servers.",
|
||||
STRQTYPE(qtype));
|
||||
#endif
|
||||
/**
|
||||
* TODO! Connection to all servers must be established, and
|
||||
* the command must be executed in them.
|
||||
@ -473,10 +484,12 @@ static int routeQuery(
|
||||
break;
|
||||
|
||||
default:
|
||||
#if defined(SS_DEBUG_)
|
||||
skygw_log_write(NULL,
|
||||
LOGFILE_TRACE,
|
||||
"Query type\t%s, routing to Master by default.",
|
||||
STRQTYPE(qtype));
|
||||
#endif
|
||||
/** Is this really ok? */
|
||||
ret = session->masterconn->func.write(session->masterconn, queue);
|
||||
atomic_add(&inst->stats.n_master, 1);
|
||||
@ -537,19 +550,25 @@ clientReply(ROUTER* instance, void* router_session, GWBUF* queue, DCB *backend_d
|
||||
{
|
||||
INSTANCE* inst = NULL;
|
||||
DCB *master = NULL;
|
||||
DCB *client = NULL;
|
||||
CLIENT_SESSION* session = NULL;
|
||||
int len = 0;
|
||||
|
||||
inst = (INSTANCE *)instance;
|
||||
session = (CLIENT_SESSION *)router_session;
|
||||
master = session->masterconn;
|
||||
client = backend_dcb->session->client;
|
||||
|
||||
/* if backend_dcb is the master reply to the client */
|
||||
if (backend_dcb == master) {
|
||||
master->session->client->func.write(master->session->client, queue);
|
||||
if (backend_dcb->command == ROUTER_CHANGE_SESSION) {
|
||||
/* if backend_dcb is the master we can reply to the client */
|
||||
if (backend_dcb == master) {
|
||||
master->session->client->func.write(master->session->client, queue);
|
||||
} else {
|
||||
/* just consume the gwbuf without writing to the client */
|
||||
gwbuf_consume(queue, gwbuf_length(queue));
|
||||
}
|
||||
} else {
|
||||
/* just consume the gwbuf without writing to the client */
|
||||
gwbuf_consume(queue, gwbuf_length(queue));
|
||||
/* normal flow */
|
||||
client->func.write(client, queue);
|
||||
}
|
||||
}
|
||||
///
|
||||
|
Reference in New Issue
Block a user