Format router modules
Formatted router modules with Astyle.
This commit is contained in:
@ -264,13 +264,13 @@ static ROUTER *createInstance(SERVICE *service, char **options)
|
||||
CONFIG_PARAMETER *params = service->svc_config_param;
|
||||
|
||||
router->rwsplit_config.use_sql_variables_in = config_get_enum(params, "use_sql_variables_in",
|
||||
use_sql_variables_in_values);
|
||||
use_sql_variables_in_values);
|
||||
|
||||
router->rwsplit_config.slave_selection_criteria = config_get_enum(params, "slave_selection_criteria",
|
||||
slave_selection_criteria_values);
|
||||
slave_selection_criteria_values);
|
||||
|
||||
router->rwsplit_config.master_failure_mode = config_get_enum(params, "master_failure_mode",
|
||||
master_failure_mode_values);
|
||||
master_failure_mode_values);
|
||||
|
||||
router->rwsplit_config.max_slave_replication_lag = config_get_integer(params, "max_slave_replication_lag");
|
||||
router->rwsplit_config.retry_failed_reads = config_get_bool(params, "retry_failed_reads");
|
||||
@ -1027,20 +1027,20 @@ void rses_property_done(rses_property_t *prop)
|
||||
|
||||
switch (prop->rses_prop_type)
|
||||
{
|
||||
case RSES_PROP_TYPE_SESCMD:
|
||||
mysql_sescmd_done(&prop->rses_prop_data.sescmd);
|
||||
break;
|
||||
case RSES_PROP_TYPE_SESCMD:
|
||||
mysql_sescmd_done(&prop->rses_prop_data.sescmd);
|
||||
break;
|
||||
|
||||
case RSES_PROP_TYPE_TMPTABLES:
|
||||
hashtable_free(prop->rses_prop_data.temp_tables);
|
||||
break;
|
||||
case RSES_PROP_TYPE_TMPTABLES:
|
||||
hashtable_free(prop->rses_prop_data.temp_tables);
|
||||
break;
|
||||
|
||||
default:
|
||||
MXS_DEBUG("%lu [rses_property_done] Unknown property type %d "
|
||||
"in property %p", pthread_self(), prop->rses_prop_type, prop);
|
||||
default:
|
||||
MXS_DEBUG("%lu [rses_property_done] Unknown property type %d "
|
||||
"in property %p", pthread_self(), prop->rses_prop_type, prop);
|
||||
|
||||
ss_dassert(false);
|
||||
break;
|
||||
ss_dassert(false);
|
||||
break;
|
||||
}
|
||||
MXS_FREE(prop);
|
||||
}
|
||||
@ -1187,12 +1187,12 @@ int router_handle_state_switch(DCB *dcb, DCB_REASON reason, void *data)
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case DCB_REASON_NOT_RESPONDING:
|
||||
dcb->func.hangup(dcb);
|
||||
break;
|
||||
case DCB_REASON_NOT_RESPONDING:
|
||||
dcb->func.hangup(dcb);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return_rc:
|
||||
@ -1386,7 +1386,7 @@ static void handleError(ROUTER *instance, void *router_session,
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ERRACT_NEW_CONNECTION:
|
||||
case ERRACT_NEW_CONNECTION:
|
||||
{
|
||||
/**
|
||||
* If master has lost its Master status error can't be
|
||||
@ -1456,7 +1456,7 @@ static void handleError(ROUTER *instance, void *router_session,
|
||||
else
|
||||
{
|
||||
const char *remote = problem_dcb->state == DCB_STATE_POLLING &&
|
||||
problem_dcb->server ? problem_dcb->server->unique_name : "CLOSED";
|
||||
problem_dcb->server ? problem_dcb->server->unique_name : "CLOSED";
|
||||
|
||||
MXS_ERROR("DCB connected to '%s' is not in use by the router "
|
||||
"session, not closing it. DCB is in state '%s'",
|
||||
@ -1465,17 +1465,17 @@ static void handleError(ROUTER *instance, void *router_session,
|
||||
break;
|
||||
}
|
||||
|
||||
case ERRACT_REPLY_CLIENT:
|
||||
case ERRACT_REPLY_CLIENT:
|
||||
{
|
||||
handle_error_reply_client(session, rses, problem_dcb, errmsgbuf);
|
||||
*succp = false; /*< no new backend servers were made available */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
*succp = false;
|
||||
break;
|
||||
default:
|
||||
ss_dassert(!true);
|
||||
*succp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
* Public License.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* File: rwsplit_internal.h
|
||||
* Author: mbrampton
|
||||
*
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
/* This needs to be removed along with dependency on it - see the
|
||||
/* This needs to be removed along with dependency on it - see the
|
||||
* rwsplit_tmp_table_multi functions
|
||||
*/
|
||||
#include <maxscale/protocol/mysql.h>
|
||||
@ -45,15 +45,15 @@ do{ \
|
||||
* The following are implemented in rwsplit_mysql.c
|
||||
*/
|
||||
bool route_single_stmt(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf);
|
||||
GWBUF *querybuf);
|
||||
void closed_session_reply(GWBUF *querybuf);
|
||||
void live_session_reply(GWBUF **querybuf, ROUTER_CLIENT_SES *rses);
|
||||
void print_error_packet(ROUTER_CLIENT_SES *rses, GWBUF *buf, DCB *dcb);
|
||||
void check_session_command_reply(GWBUF *writebuf, sescmd_cursor_t *scur, backend_ref_t *bref);
|
||||
bool execute_sescmd_in_backend(backend_ref_t *backend_ref);
|
||||
bool handle_target_is_all(route_target_t route_target,
|
||||
ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf, int packet_type, qc_query_type_t qtype);
|
||||
ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf, int packet_type, qc_query_type_t qtype);
|
||||
int determine_packet_type(GWBUF *querybuf, bool *non_empty_packet);
|
||||
void log_transaction_status(ROUTER_CLIENT_SES *rses, GWBUF *querybuf, qc_query_type_t qtype);
|
||||
void session_lock_failure_handling(GWBUF *querybuf, int packet_type, qc_query_type_t qtype);
|
||||
@ -80,74 +80,74 @@ int rses_get_max_replication_lag(ROUTER_CLIENT_SES *rses);
|
||||
*/
|
||||
|
||||
bool route_single_stmt(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf);
|
||||
GWBUF *querybuf);
|
||||
int rwsplit_hashkeyfun(const void *key);
|
||||
int rwsplit_hashcmpfun(const void *v1, const void *v2);
|
||||
void *rwsplit_hstrdup(const void *fval);
|
||||
void rwsplit_hfree(void *fval);
|
||||
bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype,
|
||||
char *name, int max_rlag);
|
||||
char *name, int max_rlag);
|
||||
route_target_t get_route_target(ROUTER_CLIENT_SES *rses,
|
||||
qc_query_type_t qtype, HINT *hint);
|
||||
qc_query_type_t qtype, HINT *hint);
|
||||
rses_property_t *rses_property_init(rses_property_type_t prop_type);
|
||||
int rses_property_add(ROUTER_CLIENT_SES *rses, rses_property_t *prop);
|
||||
void handle_multi_temp_and_load(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
int packet_type, int *qtype);
|
||||
int packet_type, int *qtype);
|
||||
bool handle_hinted_target(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
route_target_t route_target, DCB **target_dcb);
|
||||
route_target_t route_target, DCB **target_dcb);
|
||||
bool handle_slave_is_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
DCB **target_dcb);
|
||||
DCB **target_dcb);
|
||||
bool handle_master_is_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
DCB **target_dcb);
|
||||
DCB **target_dcb);
|
||||
bool handle_got_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf, DCB *target_dcb, bool store);
|
||||
GWBUF *querybuf, DCB *target_dcb, bool store);
|
||||
bool route_session_write(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf, ROUTER_INSTANCE *inst,
|
||||
int packet_type,
|
||||
qc_query_type_t qtype);
|
||||
GWBUF *querybuf, ROUTER_INSTANCE *inst,
|
||||
int packet_type,
|
||||
qc_query_type_t qtype);
|
||||
|
||||
/*
|
||||
* The following are implemented in rwsplit_session_cmd.c
|
||||
*/
|
||||
mysql_sescmd_t *rses_property_get_sescmd(rses_property_t *prop);
|
||||
mysql_sescmd_t *mysql_sescmd_init(rses_property_t *rses_prop,
|
||||
GWBUF *sescmd_buf,
|
||||
unsigned char packet_type,
|
||||
ROUTER_CLIENT_SES *rses);
|
||||
GWBUF *sescmd_buf,
|
||||
unsigned char packet_type,
|
||||
ROUTER_CLIENT_SES *rses);
|
||||
void mysql_sescmd_done(mysql_sescmd_t *sescmd);
|
||||
mysql_sescmd_t *sescmd_cursor_get_command(sescmd_cursor_t *scur);
|
||||
bool sescmd_cursor_is_active(sescmd_cursor_t *sescmd_cursor);
|
||||
void sescmd_cursor_set_active(sescmd_cursor_t *sescmd_cursor,
|
||||
bool value);
|
||||
bool value);
|
||||
bool execute_sescmd_history(backend_ref_t *bref);
|
||||
GWBUF *sescmd_cursor_clone_querybuf(sescmd_cursor_t *scur);
|
||||
GWBUF *sescmd_cursor_process_replies(GWBUF *replybuf,
|
||||
backend_ref_t *bref,
|
||||
bool *reconnect);
|
||||
backend_ref_t *bref,
|
||||
bool *reconnect);
|
||||
|
||||
/*
|
||||
* The following are implemented in rwsplit_select_backends.c
|
||||
*/
|
||||
bool select_connect_backend_servers(backend_ref_t **p_master_ref,
|
||||
backend_ref_t *backend_ref,
|
||||
int router_nservers, int max_nslaves,
|
||||
int max_slave_rlag,
|
||||
select_criteria_t select_criteria,
|
||||
SESSION *session,
|
||||
ROUTER_INSTANCE *router,
|
||||
bool active_session);
|
||||
backend_ref_t *backend_ref,
|
||||
int router_nservers, int max_nslaves,
|
||||
int max_slave_rlag,
|
||||
select_criteria_t select_criteria,
|
||||
SESSION *session,
|
||||
ROUTER_INSTANCE *router,
|
||||
bool active_session);
|
||||
|
||||
/*
|
||||
* The following are implemented in rwsplit_tmp_table_multi.c
|
||||
*/
|
||||
void check_drop_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf,
|
||||
mysql_server_cmd_t packet_type);
|
||||
void check_drop_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf,
|
||||
mysql_server_cmd_t packet_type);
|
||||
bool is_read_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf,
|
||||
qc_query_type_t type);
|
||||
GWBUF *querybuf,
|
||||
qc_query_type_t type);
|
||||
void check_create_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf, qc_query_type_t type);
|
||||
GWBUF *querybuf, qc_query_type_t type);
|
||||
bool check_for_multi_stmt(GWBUF *buf, void *protocol, mysql_server_cmd_t packet_type);
|
||||
qc_query_type_t determine_query_type(GWBUF *querybuf, int packet_type, bool non_empty_packet);
|
||||
void close_failed_bref(backend_ref_t *bref, bool fatal);
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
* It is certainly MySQL specific. Packet types are DB specific, but can be
|
||||
* assumed to be enums, which can be handled as integers without knowing
|
||||
* which DB is involved until the packet type needs to be interpreted.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -73,10 +73,10 @@
|
||||
* Examine the packet in the buffer to extract the type, if possible. At the
|
||||
* same time set the second parameter to indicate whether the packet was
|
||||
* empty.
|
||||
*
|
||||
*
|
||||
* It is assumed that the packet length and type are contained within a single
|
||||
* buffer, the one indicated by the first parameter.
|
||||
*
|
||||
*
|
||||
* @param querybuf Buffer containing the packet
|
||||
* @param non_empty_packet bool indicating whether the packet is non-empty
|
||||
* @return The packet type, or MYSQL_COM_UNDEFINED; also the second parameter is set
|
||||
@ -111,7 +111,7 @@ determine_packet_type(GWBUF *querybuf, bool *non_empty_packet)
|
||||
* provided so that code that is not DB specific can find out whether a packet
|
||||
* contains a SQL query. Clearly, to be effective different functions must be
|
||||
* called for different DB types.
|
||||
*
|
||||
*
|
||||
* @param packet_type Type of packet (integer)
|
||||
* @return bool indicating whether packet contains a SQL query
|
||||
*/
|
||||
@ -131,7 +131,7 @@ is_packet_a_query(int packet_type)
|
||||
* provided so that code that is not DB specific can find out whether a packet
|
||||
* contains a one way messsage. Clearly, to be effective different functions must be
|
||||
* called for different DB types.
|
||||
*
|
||||
*
|
||||
* @param packet_type Type of packet (integer)
|
||||
* @return bool indicating whether packet contains a one way message
|
||||
*/
|
||||
@ -139,7 +139,7 @@ bool
|
||||
is_packet_a_one_way_message(int packet_type)
|
||||
{
|
||||
return (packet_type == MYSQL_COM_STMT_SEND_LONG_DATA ||
|
||||
packet_type == MYSQL_COM_QUIT || packet_type == MYSQL_COM_STMT_CLOSE);
|
||||
packet_type == MYSQL_COM_QUIT || packet_type == MYSQL_COM_STMT_CLOSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -152,7 +152,7 @@ is_packet_a_one_way_message(int packet_type)
|
||||
* The router session and the query buffer are used to log the transaction
|
||||
* status, along with the query type (which is a generic description that
|
||||
* should be usable across all DB types).
|
||||
*
|
||||
*
|
||||
* @param rses Router session
|
||||
* @param querybuf Query buffer
|
||||
* @param qtype Query type
|
||||
@ -160,30 +160,30 @@ is_packet_a_one_way_message(int packet_type)
|
||||
void
|
||||
log_transaction_status(ROUTER_CLIENT_SES *rses, GWBUF *querybuf, qc_query_type_t qtype)
|
||||
{
|
||||
if (!rses->rses_load_active)
|
||||
{
|
||||
uint8_t *packet = GWBUF_DATA(querybuf);
|
||||
unsigned char ptype = packet[4];
|
||||
size_t len = MXS_MIN(GWBUF_LENGTH(querybuf),
|
||||
MYSQL_GET_PAYLOAD_LEN((unsigned char *)querybuf->start) - 1);
|
||||
char *data = (char *)&packet[5];
|
||||
char *contentstr = strndup(data, MXS_MIN(len, RWSPLIT_TRACE_MSG_LEN));
|
||||
char *qtypestr = qc_typemask_to_string(qtype);
|
||||
SESSION *ses = rses->client_dcb->session;
|
||||
MXS_INFO("> Autocommit: %s, trx is %s, cmd: %s, type: %s, stmt: %s%s %s",
|
||||
(session_is_autocommit(ses) ? "[enabled]" : "[disabled]"),
|
||||
(session_trx_is_active(ses) ? "[open]" : "[not open]"),
|
||||
STRPACKETTYPE(ptype), (qtypestr == NULL ? "N/A" : qtypestr),
|
||||
contentstr, (querybuf->hint == NULL ? "" : ", Hint:"),
|
||||
(querybuf->hint == NULL ? "" : STRHINTTYPE(querybuf->hint->type)));
|
||||
MXS_FREE(contentstr);
|
||||
MXS_FREE(qtypestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_INFO("> Processing LOAD DATA LOCAL INFILE: %lu bytes sent.",
|
||||
rses->rses_load_data_sent);
|
||||
}
|
||||
if (!rses->rses_load_active)
|
||||
{
|
||||
uint8_t *packet = GWBUF_DATA(querybuf);
|
||||
unsigned char ptype = packet[4];
|
||||
size_t len = MXS_MIN(GWBUF_LENGTH(querybuf),
|
||||
MYSQL_GET_PAYLOAD_LEN((unsigned char *)querybuf->start) - 1);
|
||||
char *data = (char *)&packet[5];
|
||||
char *contentstr = strndup(data, MXS_MIN(len, RWSPLIT_TRACE_MSG_LEN));
|
||||
char *qtypestr = qc_typemask_to_string(qtype);
|
||||
SESSION *ses = rses->client_dcb->session;
|
||||
MXS_INFO("> Autocommit: %s, trx is %s, cmd: %s, type: %s, stmt: %s%s %s",
|
||||
(session_is_autocommit(ses) ? "[enabled]" : "[disabled]"),
|
||||
(session_trx_is_active(ses) ? "[open]" : "[not open]"),
|
||||
STRPACKETTYPE(ptype), (qtypestr == NULL ? "N/A" : qtypestr),
|
||||
contentstr, (querybuf->hint == NULL ? "" : ", Hint:"),
|
||||
(querybuf->hint == NULL ? "" : STRHINTTYPE(querybuf->hint->type)));
|
||||
MXS_FREE(contentstr);
|
||||
MXS_FREE(qtypestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_INFO("> Processing LOAD DATA LOCAL INFILE: %lu bytes sent.",
|
||||
rses->rses_load_data_sent);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -198,22 +198,22 @@ log_transaction_status(ROUTER_CLIENT_SES *rses, GWBUF *querybuf, qc_query_type_t
|
||||
*
|
||||
* If the choice of sending to all backends is in conflict with other bit
|
||||
* settings in route_target, then error messages are written to the log.
|
||||
*
|
||||
*
|
||||
* Otherwise, the function route_session_write is called to carry out the
|
||||
* actual routing.
|
||||
*
|
||||
*
|
||||
* @param route_target Bit map indicating where packet should be routed
|
||||
* @param inst Router instance
|
||||
* @param rses Router session
|
||||
* @param querybuf Query buffer containing packet
|
||||
* @param packet_type Integer (enum) indicating type of packet
|
||||
* @param qtype Query type
|
||||
* @param qtype Query type
|
||||
* @return bool indicating whether the session can continue
|
||||
*/
|
||||
bool
|
||||
handle_target_is_all(route_target_t route_target,
|
||||
ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf, int packet_type, qc_query_type_t qtype)
|
||||
ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf, int packet_type, qc_query_type_t qtype)
|
||||
{
|
||||
bool result;
|
||||
|
||||
@ -228,12 +228,12 @@ handle_target_is_all(route_target_t route_target,
|
||||
|
||||
/* NOTE: packet_type is MySQL specific */
|
||||
MXS_ERROR("Can't route %s:%s:\"%s\". SELECT with session data "
|
||||
"modification is not supported if configuration parameter "
|
||||
"use_sql_variables_in=all .", STRPACKETTYPE(packet_type),
|
||||
qtype_str, (query_str == NULL ? "(empty)" : query_str));
|
||||
"modification is not supported if configuration parameter "
|
||||
"use_sql_variables_in=all .", STRPACKETTYPE(packet_type),
|
||||
qtype_str, (query_str == NULL ? "(empty)" : query_str));
|
||||
|
||||
MXS_INFO("Unable to route the query without losing session data "
|
||||
"modification from other servers. <");
|
||||
"modification from other servers. <");
|
||||
|
||||
while (bref != NULL && !BREF_IS_IN_USE(bref))
|
||||
{
|
||||
@ -244,9 +244,9 @@ handle_target_is_all(route_target_t route_target,
|
||||
{
|
||||
/** Create and add MySQL error to eventqueue */
|
||||
modutil_reply_parse_error(bref->bref_dcb,
|
||||
MXS_STRDUP_A("Routing query to backend failed. "
|
||||
"See the error log for further "
|
||||
"details."), 0);
|
||||
MXS_STRDUP_A("Routing query to backend failed. "
|
||||
"See the error log for further "
|
||||
"details."), 0);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
@ -256,9 +256,9 @@ handle_target_is_all(route_target_t route_target,
|
||||
* available return false - session will be closed
|
||||
*/
|
||||
MXS_ERROR("Sending error message to client "
|
||||
"failed. Router doesn't have any "
|
||||
"available backends. Session will be "
|
||||
"closed.");
|
||||
"failed. Router doesn't have any "
|
||||
"available backends. Session will be "
|
||||
"closed.");
|
||||
result = false;
|
||||
}
|
||||
/* Test shouldn't be needed */
|
||||
@ -278,7 +278,7 @@ handle_target_is_all(route_target_t route_target,
|
||||
* Router locking is done inside the function.
|
||||
*/
|
||||
result = route_session_write(rses, gwbuf_clone(querybuf), inst,
|
||||
packet_type, qtype);
|
||||
packet_type, qtype);
|
||||
|
||||
if (result)
|
||||
{
|
||||
@ -290,12 +290,12 @@ handle_target_is_all(route_target_t route_target,
|
||||
/* This is MySQL specific */
|
||||
/**
|
||||
* @brief Write an error message to the log indicating failure
|
||||
*
|
||||
*
|
||||
* Used when an attempt to lock the router session fails.
|
||||
*
|
||||
* @param querybuf Query buffer containing packet
|
||||
* @param packet_type Integer (enum) indicating type of packet
|
||||
* @param qtype Query type
|
||||
* @param qtype Query type
|
||||
*/
|
||||
void
|
||||
session_lock_failure_handling(GWBUF *querybuf, int packet_type, qc_query_type_t qtype)
|
||||
@ -306,9 +306,9 @@ session_lock_failure_handling(GWBUF *querybuf, int packet_type, qc_query_type_t
|
||||
char *query_str = modutil_get_query(querybuf);
|
||||
|
||||
MXS_ERROR("Can't route %s:%s:\"%s\" to "
|
||||
"backend server. Router is closed.",
|
||||
STRPACKETTYPE(packet_type), STRQTYPE(qtype),
|
||||
(query_str == NULL ? "(empty)" : query_str));
|
||||
"backend server. Router is closed.",
|
||||
STRPACKETTYPE(packet_type), STRQTYPE(qtype),
|
||||
(query_str == NULL ? "(empty)" : query_str));
|
||||
MXS_FREE(query_str);
|
||||
}
|
||||
}
|
||||
@ -318,7 +318,7 @@ session_lock_failure_handling(GWBUF *querybuf, int packet_type, qc_query_type_t
|
||||
*/
|
||||
/**
|
||||
* @brief Write an error message to the log for closed session
|
||||
*
|
||||
*
|
||||
* This happens if a request is received for a session that is already
|
||||
* closing down.
|
||||
*
|
||||
@ -343,8 +343,8 @@ void closed_session_reply(GWBUF *querybuf)
|
||||
*/
|
||||
/**
|
||||
* @brief First step to handle request in a live session
|
||||
*
|
||||
* Used when a request is about to be routed. Note that the query buffer is
|
||||
*
|
||||
* Used when a request is about to be routed. Note that the query buffer is
|
||||
* passed by name and is likely to be modified by this function.
|
||||
*
|
||||
* @param querybuf Query buffer containing packet
|
||||
@ -374,7 +374,7 @@ void live_session_reply(GWBUF **querybuf, ROUTER_CLIENT_SES *rses)
|
||||
*/
|
||||
/**
|
||||
* @brief Check the reply from a backend server to a session command
|
||||
*
|
||||
*
|
||||
* If the reply is an error, a message may be logged.
|
||||
*
|
||||
* @param writebuf Query buffer containing reply data
|
||||
@ -383,24 +383,24 @@ void live_session_reply(GWBUF **querybuf, ROUTER_CLIENT_SES *rses)
|
||||
*/
|
||||
void check_session_command_reply(GWBUF *writebuf, sescmd_cursor_t *scur, backend_ref_t *bref)
|
||||
{
|
||||
if (MXS_LOG_PRIORITY_IS_ENABLED(LOG_ERR) &&
|
||||
MYSQL_IS_ERROR_PACKET(((uint8_t *)GWBUF_DATA(writebuf))))
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)GWBUF_DATA((scur->scmd_cur_cmd->my_sescmd_buf));
|
||||
uint8_t *replybuf = (uint8_t *)GWBUF_DATA(writebuf);
|
||||
size_t len = MYSQL_GET_PAYLOAD_LEN(buf);
|
||||
size_t replylen = MYSQL_GET_PAYLOAD_LEN(replybuf);
|
||||
char *err = strndup(&((char *)replybuf)[8], 5);
|
||||
char *replystr = strndup(&((char *)replybuf)[13], replylen - 4 - 5);
|
||||
if (MXS_LOG_PRIORITY_IS_ENABLED(LOG_ERR) &&
|
||||
MYSQL_IS_ERROR_PACKET(((uint8_t *)GWBUF_DATA(writebuf))))
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)GWBUF_DATA((scur->scmd_cur_cmd->my_sescmd_buf));
|
||||
uint8_t *replybuf = (uint8_t *)GWBUF_DATA(writebuf);
|
||||
size_t len = MYSQL_GET_PAYLOAD_LEN(buf);
|
||||
size_t replylen = MYSQL_GET_PAYLOAD_LEN(replybuf);
|
||||
char *err = strndup(&((char *)replybuf)[8], 5);
|
||||
char *replystr = strndup(&((char *)replybuf)[13], replylen - 4 - 5);
|
||||
|
||||
ss_dassert(len + 4 == GWBUF_LENGTH(scur->scmd_cur_cmd->my_sescmd_buf));
|
||||
ss_dassert(len + 4 == GWBUF_LENGTH(scur->scmd_cur_cmd->my_sescmd_buf));
|
||||
|
||||
MXS_ERROR("Failed to execute session command in %s:%d. Error was: %s %s",
|
||||
bref->ref->server->name,
|
||||
bref->ref->server->port, err, replystr);
|
||||
MXS_FREE(err);
|
||||
MXS_FREE(replystr);
|
||||
}
|
||||
MXS_ERROR("Failed to execute session command in %s:%d. Error was: %s %s",
|
||||
bref->ref->server->name,
|
||||
bref->ref->server->port, err, replystr);
|
||||
MXS_FREE(err);
|
||||
MXS_FREE(replystr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -412,7 +412,7 @@ void check_session_command_reply(GWBUF *writebuf, sescmd_cursor_t *scur, backend
|
||||
* commands.
|
||||
*
|
||||
* Router session must be locked.
|
||||
*
|
||||
*
|
||||
* @param backend_ref Router session backend database data
|
||||
* @return bool - true for success, false for failure
|
||||
*/
|
||||
@ -464,14 +464,14 @@ bool execute_sescmd_in_backend(backend_ref_t *backend_ref)
|
||||
|
||||
switch (scur->scmd_cur_cmd->my_sescmd_packet_type)
|
||||
{
|
||||
case MYSQL_COM_CHANGE_USER:
|
||||
/** This makes it possible to handle replies correctly */
|
||||
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
|
||||
buf = sescmd_cursor_clone_querybuf(scur);
|
||||
rc = dcb->func.auth(dcb, NULL, dcb->session, buf);
|
||||
break;
|
||||
case MYSQL_COM_CHANGE_USER:
|
||||
/** This makes it possible to handle replies correctly */
|
||||
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
|
||||
buf = sescmd_cursor_clone_querybuf(scur);
|
||||
rc = dcb->func.auth(dcb, NULL, dcb->session, buf);
|
||||
break;
|
||||
|
||||
case MYSQL_COM_INIT_DB:
|
||||
case MYSQL_COM_INIT_DB:
|
||||
{
|
||||
/**
|
||||
* Record database name and store to session.
|
||||
@ -498,18 +498,18 @@ bool execute_sescmd_in_backend(backend_ref_t *backend_ref)
|
||||
data->db[qlen] = 0;
|
||||
}
|
||||
}
|
||||
/** Fallthrough */
|
||||
case MYSQL_COM_QUERY:
|
||||
default:
|
||||
/**
|
||||
* Mark session command buffer, it triggers writing
|
||||
* MySQL command to protocol
|
||||
*/
|
||||
/** Fallthrough */
|
||||
case MYSQL_COM_QUERY:
|
||||
default:
|
||||
/**
|
||||
* Mark session command buffer, it triggers writing
|
||||
* MySQL command to protocol
|
||||
*/
|
||||
|
||||
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
|
||||
buf = sescmd_cursor_clone_querybuf(scur);
|
||||
rc = dcb->func.write(dcb, buf);
|
||||
break;
|
||||
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
|
||||
buf = sescmd_cursor_clone_querybuf(scur);
|
||||
rc = dcb->func.write(dcb, buf);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == 1)
|
||||
@ -582,7 +582,7 @@ bool send_readonly_error(DCB *dcb)
|
||||
{
|
||||
bool succp = false;
|
||||
const char* errmsg = "The MariaDB server is running with the --read-only"
|
||||
" option so it cannot execute this statement";
|
||||
" option so it cannot execute this statement";
|
||||
GWBUF* err = modutil_create_mysql_err_msg(1, 0, ER_OPTION_PREVENTS_STATEMENT,
|
||||
"HY000", errmsg);
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ static backend_ref_t *get_root_master_bref(ROUTER_CLIENT_SES *rses);
|
||||
* false if backend failure was encountered.
|
||||
*/
|
||||
bool route_single_stmt(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
GWBUF *querybuf)
|
||||
GWBUF *querybuf)
|
||||
{
|
||||
qc_query_type_t qtype = QUERY_TYPE_UNKNOWN;
|
||||
int packet_type;
|
||||
@ -177,9 +177,9 @@ bool route_single_stmt(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
*
|
||||
*/
|
||||
bool route_session_write(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf, ROUTER_INSTANCE *inst,
|
||||
int packet_type,
|
||||
qc_query_type_t qtype)
|
||||
GWBUF *querybuf, ROUTER_INSTANCE *inst,
|
||||
int packet_type,
|
||||
qc_query_type_t qtype)
|
||||
{
|
||||
bool succp;
|
||||
rses_property_t *prop;
|
||||
@ -394,7 +394,7 @@ return_succp:
|
||||
|
||||
/**
|
||||
* @brief Function to hash keys in read-write split router
|
||||
*
|
||||
*
|
||||
* Used to store information about temporary tables.
|
||||
*
|
||||
* @param key key to be hashed, actually a character string
|
||||
@ -419,7 +419,7 @@ int rwsplit_hashkeyfun(const void *key)
|
||||
|
||||
/**
|
||||
* @brief Function to compare hash keys in read-write split router
|
||||
*
|
||||
*
|
||||
* Used to manage information about temporary tables.
|
||||
*
|
||||
* @param key first key to be compared, actually a character string
|
||||
@ -436,7 +436,7 @@ int rwsplit_hashcmpfun(const void *v1, const void *v2)
|
||||
|
||||
/**
|
||||
* @brief Function to duplicate a hash value in read-write split router
|
||||
*
|
||||
*
|
||||
* Used to manage information about temporary tables.
|
||||
*
|
||||
* @param fval value to be duplicated, actually a character string
|
||||
@ -450,7 +450,7 @@ void *rwsplit_hstrdup(const void *fval)
|
||||
|
||||
/**
|
||||
* @brief Function to free hash values in read-write split router
|
||||
*
|
||||
*
|
||||
* Used to manage information about temporary tables.
|
||||
*
|
||||
* @param key value to be freed
|
||||
@ -476,7 +476,7 @@ void rwsplit_hfree(void *fval)
|
||||
* @return True if proper DCB was found, false otherwise.
|
||||
*/
|
||||
bool rwsplit_get_dcb(DCB **p_dcb, ROUTER_CLIENT_SES *rses, backend_type_t btype,
|
||||
char *name, int max_rlag)
|
||||
char *name, int max_rlag)
|
||||
{
|
||||
backend_ref_t *backend_ref;
|
||||
backend_ref_t *master_bref;
|
||||
@ -771,9 +771,9 @@ route_target_t get_route_target(ROUTER_CLIENT_SES *rses,
|
||||
}
|
||||
}
|
||||
else if (qc_query_is_type(qtype, QUERY_TYPE_READ) || // Normal read
|
||||
qc_query_is_type(qtype, QUERY_TYPE_SHOW_TABLES) || // SHOW TABLES
|
||||
qc_query_is_type(qtype, QUERY_TYPE_SYSVAR_READ) || // System variable
|
||||
qc_query_is_type(qtype, QUERY_TYPE_GSYSVAR_READ)) // Global system variable
|
||||
qc_query_is_type(qtype, QUERY_TYPE_SHOW_TABLES) || // SHOW TABLES
|
||||
qc_query_is_type(qtype, QUERY_TYPE_SYSVAR_READ) || // System variable
|
||||
qc_query_is_type(qtype, QUERY_TYPE_GSYSVAR_READ)) // Global system variable
|
||||
{
|
||||
target = TARGET_SLAVE;
|
||||
}
|
||||
@ -809,9 +809,9 @@ route_target_t get_route_target(ROUTER_CLIENT_SES *rses,
|
||||
qc_query_is_type(qtype, QUERY_TYPE_CREATE_TMP_TABLE) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_READ_TMP_TABLE) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_UNKNOWN)) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_EXEC_STMT) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_PREPARE_STMT) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_PREPARE_NAMED_STMT));
|
||||
qc_query_is_type(qtype, QUERY_TYPE_EXEC_STMT) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_PREPARE_STMT) ||
|
||||
qc_query_is_type(qtype, QUERY_TYPE_PREPARE_NAMED_STMT));
|
||||
target = TARGET_MASTER;
|
||||
}
|
||||
|
||||
@ -874,7 +874,7 @@ route_target_t get_route_target(ROUTER_CLIENT_SES *rses,
|
||||
|
||||
/**
|
||||
* @brief Handle multi statement queries and load statements
|
||||
*
|
||||
*
|
||||
* One of the possible types of handling required when a request is routed
|
||||
*
|
||||
* @param ses Router session
|
||||
@ -884,104 +884,104 @@ route_target_t get_route_target(ROUTER_CLIENT_SES *rses,
|
||||
*/
|
||||
void
|
||||
handle_multi_temp_and_load(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
int packet_type, int *qtype)
|
||||
int packet_type, int *qtype)
|
||||
{
|
||||
/** Check for multi-statement queries. If no master server is available
|
||||
* and a multi-statement is issued, an error is returned to the client
|
||||
* when the query is routed.
|
||||
*
|
||||
* If we do not have a master node, assigning the forced node is not
|
||||
* effective since we don't have a node to force queries to. In this
|
||||
* situation, assigning QUERY_TYPE_WRITE for the query will trigger
|
||||
* the error processing. */
|
||||
if ((rses->forced_node == NULL || rses->forced_node != rses->rses_master_ref) &&
|
||||
check_for_multi_stmt(querybuf, rses->client_dcb->protocol, packet_type))
|
||||
/** Check for multi-statement queries. If no master server is available
|
||||
* and a multi-statement is issued, an error is returned to the client
|
||||
* when the query is routed.
|
||||
*
|
||||
* If we do not have a master node, assigning the forced node is not
|
||||
* effective since we don't have a node to force queries to. In this
|
||||
* situation, assigning QUERY_TYPE_WRITE for the query will trigger
|
||||
* the error processing. */
|
||||
if ((rses->forced_node == NULL || rses->forced_node != rses->rses_master_ref) &&
|
||||
check_for_multi_stmt(querybuf, rses->client_dcb->protocol, packet_type))
|
||||
{
|
||||
if (rses->rses_master_ref)
|
||||
{
|
||||
if (rses->rses_master_ref)
|
||||
{
|
||||
rses->forced_node = rses->rses_master_ref;
|
||||
MXS_INFO("Multi-statement query, routing all future queries to master.");
|
||||
}
|
||||
else
|
||||
{
|
||||
*qtype |= QUERY_TYPE_WRITE;
|
||||
}
|
||||
rses->forced_node = rses->rses_master_ref;
|
||||
MXS_INFO("Multi-statement query, routing all future queries to master.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Make checks prior to calling temp tables functions
|
||||
*/
|
||||
|
||||
if (rses == NULL || querybuf == NULL ||
|
||||
rses->client_dcb == NULL || rses->client_dcb->data == NULL)
|
||||
{
|
||||
if (rses == NULL || querybuf == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: NULL variables for temp table checks: %p %p", __FUNCTION__,
|
||||
rses, querybuf);
|
||||
}
|
||||
|
||||
if (rses->client_dcb == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (rses->client_dcb->data == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: User data in master server DBC is NULL.",
|
||||
__FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Check if the query has anything to do with temporary tables.
|
||||
*/
|
||||
if (rses->have_tmp_tables)
|
||||
{
|
||||
check_drop_tmp_table(rses, querybuf, packet_type);
|
||||
if (is_packet_a_query(packet_type) && is_read_tmp_table(rses, querybuf, *qtype))
|
||||
{
|
||||
*qtype |= QUERY_TYPE_MASTER_READ;
|
||||
}
|
||||
}
|
||||
check_create_tmp_table(rses, querybuf, *qtype);
|
||||
*qtype |= QUERY_TYPE_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make checks prior to calling temp tables functions
|
||||
*/
|
||||
|
||||
if (rses == NULL || querybuf == NULL ||
|
||||
rses->client_dcb == NULL || rses->client_dcb->data == NULL)
|
||||
{
|
||||
if (rses == NULL || querybuf == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: NULL variables for temp table checks: %p %p", __FUNCTION__,
|
||||
rses, querybuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a LOAD DATA LOCAL INFILE query. If so, send all queries
|
||||
* to the master until the last, empty packet arrives.
|
||||
*/
|
||||
if (rses->rses_load_active)
|
||||
if (rses->client_dcb == NULL)
|
||||
{
|
||||
rses->rses_load_data_sent += gwbuf_length(querybuf);
|
||||
MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__);
|
||||
}
|
||||
else if (is_packet_a_query(packet_type))
|
||||
|
||||
if (rses->client_dcb->data == NULL)
|
||||
{
|
||||
qc_query_op_t queryop = qc_get_operation(querybuf);
|
||||
if (queryop == QUERY_OP_LOAD)
|
||||
MXS_ERROR("[%s] Error: User data in master server DBC is NULL.",
|
||||
__FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Check if the query has anything to do with temporary tables.
|
||||
*/
|
||||
if (rses->have_tmp_tables)
|
||||
{
|
||||
check_drop_tmp_table(rses, querybuf, packet_type);
|
||||
if (is_packet_a_query(packet_type) && is_read_tmp_table(rses, querybuf, *qtype))
|
||||
{
|
||||
rses->rses_load_active = true;
|
||||
rses->rses_load_data_sent = 0;
|
||||
*qtype |= QUERY_TYPE_MASTER_READ;
|
||||
}
|
||||
}
|
||||
check_create_tmp_table(rses, querybuf, *qtype);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a LOAD DATA LOCAL INFILE query. If so, send all queries
|
||||
* to the master until the last, empty packet arrives.
|
||||
*/
|
||||
if (rses->rses_load_active)
|
||||
{
|
||||
rses->rses_load_data_sent += gwbuf_length(querybuf);
|
||||
}
|
||||
else if (is_packet_a_query(packet_type))
|
||||
{
|
||||
qc_query_op_t queryop = qc_get_operation(querybuf);
|
||||
if (queryop == QUERY_OP_LOAD)
|
||||
{
|
||||
rses->rses_load_active = true;
|
||||
rses->rses_load_data_sent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle hinted target query
|
||||
*
|
||||
*
|
||||
* One of the possible types of handling required when a request is routed
|
||||
*
|
||||
* @param ses Router session
|
||||
* @param querybuf Buffer containing query to be routed
|
||||
* @param route_target Target for the query
|
||||
* @param target_dcb DCB for the target server
|
||||
*
|
||||
*
|
||||
* @return bool - true if succeeded, false otherwise
|
||||
*/
|
||||
bool handle_hinted_target(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
route_target_t route_target, DCB **target_dcb)
|
||||
route_target_t route_target, DCB **target_dcb)
|
||||
{
|
||||
HINT *hint;
|
||||
char *named_server = NULL;
|
||||
@ -1003,8 +1003,8 @@ bool handle_hinted_target(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
MXS_INFO("Hint: route to server '%s'", named_server);
|
||||
}
|
||||
else if (hint->type == HINT_PARAMETER &&
|
||||
(strncasecmp((char *)hint->data, "max_slave_replication_lag",
|
||||
strlen("max_slave_replication_lag")) == 0))
|
||||
(strncasecmp((char *)hint->data, "max_slave_replication_lag",
|
||||
strlen("max_slave_replication_lag")) == 0))
|
||||
{
|
||||
int val = (int)strtol((char *)hint->value, (char **)NULL, 10);
|
||||
|
||||
@ -1037,14 +1037,14 @@ bool handle_hinted_target(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
if (TARGET_IS_NAMED_SERVER(route_target))
|
||||
{
|
||||
MXS_INFO("Was supposed to route to named server "
|
||||
"%s but couldn't find the server in a "
|
||||
"suitable state.", named_server);
|
||||
"%s but couldn't find the server in a "
|
||||
"suitable state.", named_server);
|
||||
}
|
||||
else if (TARGET_IS_RLAG_MAX(route_target))
|
||||
{
|
||||
MXS_INFO("Was supposed to route to server with "
|
||||
"replication lag at most %d but couldn't "
|
||||
"find such a slave.", rlag_max);
|
||||
"replication lag at most %d but couldn't "
|
||||
"find such a slave.", rlag_max);
|
||||
}
|
||||
}
|
||||
return succp;
|
||||
@ -1052,17 +1052,17 @@ bool handle_hinted_target(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
|
||||
/**
|
||||
* @brief Handle slave is the target
|
||||
*
|
||||
*
|
||||
* One of the possible types of handling required when a request is routed
|
||||
*
|
||||
* @param inst Router instance
|
||||
* @param ses Router session
|
||||
* @param target_dcb DCB for the target server
|
||||
*
|
||||
*
|
||||
* @return bool - true if succeeded, false otherwise
|
||||
*/
|
||||
bool handle_slave_is_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
DCB **target_dcb)
|
||||
DCB **target_dcb)
|
||||
{
|
||||
int rlag_max = rses_get_max_replication_lag(rses);
|
||||
|
||||
@ -1093,7 +1093,7 @@ static void log_master_routing_failure(ROUTER_CLIENT_SES *rses, bool found,
|
||||
|
||||
if (!found)
|
||||
{
|
||||
sprintf(errmsg, "Could not find a valid master connection");
|
||||
sprintf(errmsg, "Could not find a valid master connection");
|
||||
}
|
||||
else if (master_dcb && curr_master_dcb)
|
||||
{
|
||||
@ -1141,13 +1141,13 @@ static void log_master_routing_failure(ROUTER_CLIENT_SES *rses, bool found,
|
||||
|
||||
/**
|
||||
* @brief Handle master is the target
|
||||
*
|
||||
*
|
||||
* One of the possible types of handling required when a request is routed
|
||||
*
|
||||
* @param inst Router instance
|
||||
* @param ses Router session
|
||||
* @param target_dcb DCB for the target server
|
||||
*
|
||||
*
|
||||
* @return bool - true if succeeded, false otherwise
|
||||
*/
|
||||
bool handle_master_is_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
@ -1197,14 +1197,14 @@ bool handle_master_is_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
|
||||
/**
|
||||
* @brief Handle got a target
|
||||
*
|
||||
*
|
||||
* One of the possible types of handling required when a request is routed
|
||||
*
|
||||
* @param inst Router instance
|
||||
* @param ses Router session
|
||||
* @param querybuf Buffer containing query to be routed
|
||||
* @param target_dcb DCB for the target server
|
||||
*
|
||||
*
|
||||
* @return bool - true if succeeded, false otherwise
|
||||
*/
|
||||
bool
|
||||
@ -1220,8 +1220,8 @@ handle_got_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
ss_dassert(target_dcb != NULL);
|
||||
|
||||
MXS_INFO("Route query to %s \t%s:%d <",
|
||||
(SERVER_IS_MASTER(bref->ref->server) ? "master"
|
||||
: "slave"), bref->ref->server->name, bref->ref->server->port);
|
||||
(SERVER_IS_MASTER(bref->ref->server) ? "master"
|
||||
: "slave"), bref->ref->server->name, bref->ref->server->port);
|
||||
/**
|
||||
* Store current statement if execution of previous session command is still
|
||||
* active. Since the master server's response is always used, we can safely
|
||||
@ -1260,9 +1260,9 @@ handle_got_target(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
|
||||
/**
|
||||
* @brief Create a generic router session property structure.
|
||||
*
|
||||
*
|
||||
* @param prop_type Property type
|
||||
*
|
||||
*
|
||||
* @return property structure of requested type, or NULL if failed
|
||||
*/
|
||||
rses_property_t *rses_property_init(rses_property_type_t prop_type)
|
||||
@ -1286,16 +1286,16 @@ rses_property_t *rses_property_init(rses_property_type_t prop_type)
|
||||
|
||||
/**
|
||||
* @brief Add property to the router client session
|
||||
*
|
||||
*
|
||||
* Add property to the router_client_ses structure's rses_properties
|
||||
* array. The slot is determined by the type of property.
|
||||
* In each slot there is a list of properties of similar type.
|
||||
*
|
||||
* Router client session must be locked.
|
||||
*
|
||||
*
|
||||
* @param rses Router session
|
||||
* @param prop Router session property to be added
|
||||
*
|
||||
*
|
||||
* @return -1 on failure, 0 on success
|
||||
*/
|
||||
int rses_property_add(ROUTER_CLIENT_SES *rses, rses_property_t *prop)
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
#include "rwsplit_internal.h"
|
||||
/**
|
||||
* @file rwsplit_select_backends.c The functions that implement back end
|
||||
* selection for the read write split router. All of these functions are
|
||||
* selection for the read write split router. All of these functions are
|
||||
* internal to that router and not intended to be called from elsewhere.
|
||||
*
|
||||
* @verbatim
|
||||
@ -38,7 +38,7 @@
|
||||
static bool connect_server(backend_ref_t *bref, SESSION *session, bool execute_history);
|
||||
|
||||
static void log_server_connections(select_criteria_t select_criteria,
|
||||
backend_ref_t *backend_ref, int router_nservers);
|
||||
backend_ref_t *backend_ref, int router_nservers);
|
||||
|
||||
static SERVER_REF *get_root_master(backend_ref_t *servers, int router_nservers);
|
||||
|
||||
@ -86,7 +86,7 @@ static bool bref_valid_for_slave(const backend_ref_t *bref, const SERVER *master
|
||||
SERVER *server = bref->ref->server;
|
||||
|
||||
return (SERVER_IS_SLAVE(server) || SERVER_IS_RELAY_SERVER(server)) &&
|
||||
(master_host == NULL || (server != master_host));
|
||||
(master_host == NULL || (server != master_host));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,13 +148,13 @@ backend_ref_t* get_slave_candidate(backend_ref_t *bref, int n, const SERVER *mas
|
||||
* @return true, if at least one master and one slave was found.
|
||||
*/
|
||||
bool select_connect_backend_servers(backend_ref_t **p_master_ref,
|
||||
backend_ref_t *backend_ref,
|
||||
int router_nservers, int max_nslaves,
|
||||
int max_slave_rlag,
|
||||
select_criteria_t select_criteria,
|
||||
SESSION *session,
|
||||
ROUTER_INSTANCE *router,
|
||||
bool active_session)
|
||||
backend_ref_t *backend_ref,
|
||||
int router_nservers, int max_nslaves,
|
||||
int max_slave_rlag,
|
||||
select_criteria_t select_criteria,
|
||||
SESSION *session,
|
||||
ROUTER_INSTANCE *router,
|
||||
bool active_session)
|
||||
{
|
||||
if (p_master_ref == NULL || backend_ref == NULL)
|
||||
{
|
||||
@ -285,7 +285,7 @@ bool select_connect_backend_servers(backend_ref_t **p_master_ref,
|
||||
} /* for */
|
||||
}
|
||||
}
|
||||
/** Failure cases */
|
||||
/** Failure cases */
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Couldn't establish required amount of slave connections for "
|
||||
@ -471,7 +471,7 @@ static bool connect_server(backend_ref_t *bref, SESSION *session, bool execute_h
|
||||
* @param router_nservers Number of backends in @p backend_ref
|
||||
*/
|
||||
static void log_server_connections(select_criteria_t select_criteria,
|
||||
backend_ref_t *backend_ref, int router_nservers)
|
||||
backend_ref_t *backend_ref, int router_nservers)
|
||||
{
|
||||
if (select_criteria == LEAST_GLOBAL_CONNECTIONS ||
|
||||
select_criteria == LEAST_ROUTER_CONNECTIONS ||
|
||||
@ -488,31 +488,31 @@ static void log_server_connections(select_criteria_t select_criteria,
|
||||
|
||||
switch (select_criteria)
|
||||
{
|
||||
case LEAST_GLOBAL_CONNECTIONS:
|
||||
MXS_INFO("MaxScale connections : %d in \t%s:%d %s",
|
||||
b->server->stats.n_current, b->server->name,
|
||||
b->server->port, STRSRVSTATUS(b->server));
|
||||
break;
|
||||
case LEAST_GLOBAL_CONNECTIONS:
|
||||
MXS_INFO("MaxScale connections : %d in \t%s:%d %s",
|
||||
b->server->stats.n_current, b->server->name,
|
||||
b->server->port, STRSRVSTATUS(b->server));
|
||||
break;
|
||||
|
||||
case LEAST_ROUTER_CONNECTIONS:
|
||||
MXS_INFO("RWSplit connections : %d in \t%s:%d %s",
|
||||
b->connections, b->server->name,
|
||||
b->server->port, STRSRVSTATUS(b->server));
|
||||
break;
|
||||
case LEAST_ROUTER_CONNECTIONS:
|
||||
MXS_INFO("RWSplit connections : %d in \t%s:%d %s",
|
||||
b->connections, b->server->name,
|
||||
b->server->port, STRSRVSTATUS(b->server));
|
||||
break;
|
||||
|
||||
case LEAST_CURRENT_OPERATIONS:
|
||||
MXS_INFO("current operations : %d in \t%s:%d %s",
|
||||
b->server->stats.n_current_ops,
|
||||
b->server->name, b->server->port,
|
||||
STRSRVSTATUS(b->server));
|
||||
break;
|
||||
case LEAST_CURRENT_OPERATIONS:
|
||||
MXS_INFO("current operations : %d in \t%s:%d %s",
|
||||
b->server->stats.n_current_ops,
|
||||
b->server->name, b->server->port,
|
||||
STRSRVSTATUS(b->server));
|
||||
break;
|
||||
|
||||
case LEAST_BEHIND_MASTER:
|
||||
MXS_INFO("replication lag : %d in \t%s:%d %s",
|
||||
b->server->rlag, b->server->name,
|
||||
b->server->port, STRSRVSTATUS(b->server));
|
||||
default:
|
||||
break;
|
||||
case LEAST_BEHIND_MASTER:
|
||||
MXS_INFO("replication lag : %d in \t%s:%d %s",
|
||||
b->server->rlag, b->server->name,
|
||||
b->server->port, STRSRVSTATUS(b->server));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,9 +76,9 @@ mysql_sescmd_t *rses_property_get_sescmd(rses_property_t *prop)
|
||||
* Create session command property.
|
||||
*/
|
||||
mysql_sescmd_t *mysql_sescmd_init(rses_property_t *rses_prop,
|
||||
GWBUF *sescmd_buf,
|
||||
unsigned char packet_type,
|
||||
ROUTER_CLIENT_SES *rses)
|
||||
GWBUF *sescmd_buf,
|
||||
unsigned char packet_type,
|
||||
ROUTER_CLIENT_SES *rses)
|
||||
{
|
||||
mysql_sescmd_t *sescmd;
|
||||
|
||||
@ -131,8 +131,8 @@ void mysql_sescmd_done(mysql_sescmd_t *sescmd)
|
||||
* 9. s+q+
|
||||
*/
|
||||
GWBUF *sescmd_cursor_process_replies(GWBUF *replybuf,
|
||||
backend_ref_t *bref,
|
||||
bool *reconnect)
|
||||
backend_ref_t *bref,
|
||||
bool *reconnect)
|
||||
{
|
||||
mysql_sescmd_t *scmd;
|
||||
sescmd_cursor_t *scur;
|
||||
@ -176,7 +176,7 @@ GWBUF *sescmd_cursor_process_replies(GWBUF *replybuf,
|
||||
MXS_ERROR("Slave server '%s': response differs from master's response. "
|
||||
"Closing connection due to inconsistent session state.",
|
||||
bref->ref->server->unique_name);
|
||||
close_failed_bref(bref, true);
|
||||
close_failed_bref(bref, true);
|
||||
|
||||
RW_CHK_DCB(bref, bref->bref_dcb);
|
||||
dcb_close(bref->bref_dcb);
|
||||
@ -301,7 +301,7 @@ bool sescmd_cursor_is_active(sescmd_cursor_t *sescmd_cursor)
|
||||
|
||||
/** router must be locked */
|
||||
void sescmd_cursor_set_active(sescmd_cursor_t *sescmd_cursor,
|
||||
bool value)
|
||||
bool value)
|
||||
{
|
||||
ss_dassert(SPINLOCK_IS_LOCKED(&sescmd_cursor->scmd_cur_rses->rses_lock));
|
||||
/** avoid calling unnecessarily */
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
/**
|
||||
* @brief Check for dropping of temporary tables
|
||||
*
|
||||
*
|
||||
* Check if the query is a DROP TABLE... query and
|
||||
* if it targets a temporary table, remove it from the hashtable.
|
||||
* @param router_cli_ses Router client session
|
||||
@ -55,7 +55,7 @@
|
||||
* @param type The type of the query resolved so far
|
||||
*/
|
||||
void check_drop_tmp_table(ROUTER_CLIENT_SES *router_cli_ses, GWBUF *querybuf,
|
||||
mysql_server_cmd_t packet_type)
|
||||
mysql_server_cmd_t packet_type)
|
||||
{
|
||||
if (packet_type != MYSQL_COM_QUERY && packet_type != MYSQL_COM_DROP_DB)
|
||||
{
|
||||
@ -112,8 +112,8 @@ void check_drop_tmp_table(ROUTER_CLIENT_SES *router_cli_ses, GWBUF *querybuf,
|
||||
* @return The type of the query
|
||||
*/
|
||||
bool is_read_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf,
|
||||
qc_query_type_t qtype)
|
||||
GWBUF *querybuf,
|
||||
qc_query_type_t qtype)
|
||||
{
|
||||
|
||||
bool target_tmp_table = false;
|
||||
@ -199,7 +199,7 @@ bool is_read_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
* @param type The type of the query resolved so far
|
||||
*/
|
||||
void check_create_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf, qc_query_type_t type)
|
||||
GWBUF *querybuf, qc_query_type_t type)
|
||||
{
|
||||
if (!qc_query_is_type(type, QUERY_TYPE_CREATE_TMP_TABLE))
|
||||
{
|
||||
@ -357,11 +357,11 @@ bool check_for_multi_stmt(GWBUF *buf, void *protocol, mysql_server_cmd_t packet_
|
||||
|
||||
/**
|
||||
* @brief Determine the type of a query
|
||||
*
|
||||
*
|
||||
* @param querybuf GWBUF containing the query
|
||||
* @param packet_type Integer denoting DB specific enum
|
||||
* @param non_empty_packet Boolean to be set by this function
|
||||
*
|
||||
*
|
||||
* @return qc_query_type_t the query type; also the non_empty_packet bool is set
|
||||
*/
|
||||
qc_query_type_t
|
||||
@ -374,47 +374,47 @@ determine_query_type(GWBUF *querybuf, int packet_type, bool non_empty_packet)
|
||||
mysql_server_cmd_t my_packet_type = (mysql_server_cmd_t)packet_type;
|
||||
switch (my_packet_type)
|
||||
{
|
||||
case MYSQL_COM_QUIT: /*< 1 QUIT will close all sessions */
|
||||
case MYSQL_COM_INIT_DB: /*< 2 DDL must go to the master */
|
||||
case MYSQL_COM_REFRESH: /*< 7 - I guess this is session but not sure */
|
||||
case MYSQL_COM_DEBUG: /*< 0d all servers dump debug info to stdout */
|
||||
case MYSQL_COM_PING: /*< 0e all servers are pinged */
|
||||
case MYSQL_COM_CHANGE_USER: /*< 11 all servers change it accordingly */
|
||||
qtype = QUERY_TYPE_SESSION_WRITE;
|
||||
break;
|
||||
case MYSQL_COM_QUIT: /*< 1 QUIT will close all sessions */
|
||||
case MYSQL_COM_INIT_DB: /*< 2 DDL must go to the master */
|
||||
case MYSQL_COM_REFRESH: /*< 7 - I guess this is session but not sure */
|
||||
case MYSQL_COM_DEBUG: /*< 0d all servers dump debug info to stdout */
|
||||
case MYSQL_COM_PING: /*< 0e all servers are pinged */
|
||||
case MYSQL_COM_CHANGE_USER: /*< 11 all servers change it accordingly */
|
||||
qtype = QUERY_TYPE_SESSION_WRITE;
|
||||
break;
|
||||
|
||||
case MYSQL_COM_CREATE_DB: /**< 5 DDL must go to the master */
|
||||
case MYSQL_COM_DROP_DB: /**< 6 DDL must go to the master */
|
||||
case MYSQL_COM_STMT_CLOSE: /*< free prepared statement */
|
||||
case MYSQL_COM_STMT_SEND_LONG_DATA: /*< send data to column */
|
||||
case MYSQL_COM_STMT_RESET: /*< resets the data of a prepared statement */
|
||||
qtype = QUERY_TYPE_WRITE;
|
||||
break;
|
||||
case MYSQL_COM_CREATE_DB: /**< 5 DDL must go to the master */
|
||||
case MYSQL_COM_DROP_DB: /**< 6 DDL must go to the master */
|
||||
case MYSQL_COM_STMT_CLOSE: /*< free prepared statement */
|
||||
case MYSQL_COM_STMT_SEND_LONG_DATA: /*< send data to column */
|
||||
case MYSQL_COM_STMT_RESET: /*< resets the data of a prepared statement */
|
||||
qtype = QUERY_TYPE_WRITE;
|
||||
break;
|
||||
|
||||
case MYSQL_COM_QUERY:
|
||||
qtype = qc_get_type(querybuf);
|
||||
break;
|
||||
case MYSQL_COM_QUERY:
|
||||
qtype = qc_get_type(querybuf);
|
||||
break;
|
||||
|
||||
case MYSQL_COM_STMT_PREPARE:
|
||||
qtype = qc_get_type(querybuf);
|
||||
qtype |= QUERY_TYPE_PREPARE_STMT;
|
||||
break;
|
||||
case MYSQL_COM_STMT_PREPARE:
|
||||
qtype = qc_get_type(querybuf);
|
||||
qtype |= QUERY_TYPE_PREPARE_STMT;
|
||||
break;
|
||||
|
||||
case MYSQL_COM_STMT_EXECUTE:
|
||||
/** Parsing is not needed for this type of packet */
|
||||
qtype = QUERY_TYPE_EXEC_STMT;
|
||||
break;
|
||||
case MYSQL_COM_STMT_EXECUTE:
|
||||
/** Parsing is not needed for this type of packet */
|
||||
qtype = QUERY_TYPE_EXEC_STMT;
|
||||
break;
|
||||
|
||||
case MYSQL_COM_SHUTDOWN: /**< 8 where should shutdown be routed ? */
|
||||
case MYSQL_COM_STATISTICS: /**< 9 ? */
|
||||
case MYSQL_COM_PROCESS_INFO: /**< 0a ? */
|
||||
case MYSQL_COM_CONNECT: /**< 0b ? */
|
||||
case MYSQL_COM_PROCESS_KILL: /**< 0c ? */
|
||||
case MYSQL_COM_TIME: /**< 0f should this be run in gateway ? */
|
||||
case MYSQL_COM_DELAYED_INSERT: /**< 10 ? */
|
||||
case MYSQL_COM_DAEMON: /**< 1d ? */
|
||||
default:
|
||||
break;
|
||||
case MYSQL_COM_SHUTDOWN: /**< 8 where should shutdown be routed ? */
|
||||
case MYSQL_COM_STATISTICS: /**< 9 ? */
|
||||
case MYSQL_COM_PROCESS_INFO: /**< 0a ? */
|
||||
case MYSQL_COM_CONNECT: /**< 0b ? */
|
||||
case MYSQL_COM_PROCESS_KILL: /**< 0c ? */
|
||||
case MYSQL_COM_TIME: /**< 0f should this be run in gateway ? */
|
||||
case MYSQL_COM_DELAYED_INSERT: /**< 10 ? */
|
||||
case MYSQL_COM_DAEMON: /**< 1d ? */
|
||||
default:
|
||||
break;
|
||||
} /**< switch by packet type */
|
||||
}
|
||||
return qtype;
|
||||
|
||||
Reference in New Issue
Block a user