Complementary fix to #694,http://bugs.mariadb.com/show_bug.cgi?id=694
RWSplit router handles query processing errors that happened in router by sending parse error reply to client. routeQuery fails only when backend has failed.
This commit is contained in:
@ -357,8 +357,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
dcb->delayq,
|
||||
GWBUF_LENGTH(dcb->delayq))) != NULL);
|
||||
}
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
{
|
||||
GWBUF* errbuf;
|
||||
bool succp;
|
||||
@ -1464,7 +1463,7 @@ static int gw_change_user(
|
||||
rv = 0;
|
||||
goto retblock;
|
||||
}
|
||||
/** Set flags that help router to identify session commans reply */
|
||||
/** Set flags that help router to identify session commands reply */
|
||||
gwbuf_set_type(buf, GWBUF_TYPE_MYSQL);
|
||||
gwbuf_set_type(buf, GWBUF_TYPE_SESCMD_RESPONSE);
|
||||
gwbuf_set_type(buf, GWBUF_TYPE_RESPONSE_END);
|
||||
|
||||
@ -865,7 +865,7 @@ int gw_read_client_event(
|
||||
rc = SESSION_ROUTE_QUERY(session, read_buffer);
|
||||
}
|
||||
|
||||
/** succeed */
|
||||
/** Routing succeed */
|
||||
if (rc)
|
||||
{
|
||||
rc = 0; /**< here '0' means success */
|
||||
@ -874,25 +874,6 @@ int gw_read_client_event(
|
||||
{
|
||||
bool succp;
|
||||
GWBUF* errbuf;
|
||||
|
||||
/**
|
||||
* Create error to be sent to client if session
|
||||
* can't be continued.
|
||||
*/
|
||||
errbuf = mysql_create_custom_error(
|
||||
1,
|
||||
0,
|
||||
"Routing query to backend failed. See "
|
||||
"the error log for further details.");
|
||||
|
||||
router->handleError(
|
||||
router_instance,
|
||||
session->router_session,
|
||||
errbuf,
|
||||
dcb,
|
||||
ERRACT_REPLY_CLIENT,
|
||||
&succp);
|
||||
free(errbuf);
|
||||
/**
|
||||
* Create error to be sent to client if session
|
||||
* can't be continued.
|
||||
@ -903,10 +884,10 @@ int gw_read_client_event(
|
||||
"Routing failed. Session is closed.");
|
||||
/**
|
||||
* Ensure that there are enough backends
|
||||
* available.
|
||||
* available.
|
||||
*/
|
||||
router->handleError(
|
||||
router_instance,
|
||||
router_instance,
|
||||
session->router_session,
|
||||
errbuf,
|
||||
dcb,
|
||||
|
||||
@ -1972,7 +1972,16 @@ retblock:
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Routing function. Find out query type, backend type, and target DCB(s).
|
||||
* Then route query to found target(s).
|
||||
* @param inst router instance
|
||||
* @param rses router session
|
||||
* @param querybuf GWBUF including the query
|
||||
*
|
||||
* @return true if routing succeed or if it failed due to unsupported query.
|
||||
* false if backend failure was encountered.
|
||||
*/
|
||||
static bool route_single_stmt(
|
||||
ROUTER_INSTANCE* inst,
|
||||
ROUTER_CLIENT_SES* rses,
|
||||
@ -2162,6 +2171,8 @@ static bool route_single_stmt(
|
||||
if (TARGET_IS_MASTER(route_target) ||
|
||||
TARGET_IS_SLAVE(route_target))
|
||||
{
|
||||
backend_ref_t* bref = rses->rses_backend_ref;
|
||||
|
||||
char* query_str = modutil_get_query(querybuf);
|
||||
char* qtype_str = skygw_get_qtype_str(qtype);
|
||||
|
||||
@ -2181,9 +2192,22 @@ static bool route_single_stmt(
|
||||
"modification from other "
|
||||
"servers. <")));
|
||||
|
||||
while (bref != NULL && !BREF_IS_IN_USE(bref))
|
||||
{
|
||||
bref++;
|
||||
}
|
||||
|
||||
if (bref != NULL && BREF_IS_IN_USE(bref))
|
||||
{
|
||||
modutil_reply_parse_error(
|
||||
bref->bref_dcb,
|
||||
strdup("Routing query to backend failed. "
|
||||
"See the error log for further "
|
||||
"details."));
|
||||
}
|
||||
if (query_str) free (query_str);
|
||||
if (qtype_str) free(qtype_str);
|
||||
succp = false;
|
||||
succp = true;
|
||||
goto retblock;
|
||||
}
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user