MXS-1295: Add strict_sp_calls
parameter
The new parameter allows the session to be "locked" to the master server after a stored procedure is called. This will keep the session state consistent if the stored procedure call modifies the state of the session.
This commit is contained in:
parent
9d9cffe4c7
commit
9046db06c5
@ -221,6 +221,15 @@ multi-statement queries.
|
||||
router_options=strict_multi_stmt=false
|
||||
```
|
||||
|
||||
### `strict_sp_calls`
|
||||
|
||||
Similar to `strict_multi_stmt`, this option allows all queries after a CALL
|
||||
operation on a stored procedure to be routed to the master. This option is
|
||||
disabled by default and was added in MaxScale 2.1.9.
|
||||
|
||||
All warnings and restrictions that apply to `strict_multi_stmt` also apply to
|
||||
`strict_sp_calls`.
|
||||
|
||||
### `master_failure_mode`
|
||||
|
||||
This option controls how the failure of a master server is handled. By default,
|
||||
|
@ -195,6 +195,7 @@ MXS_MODULE *MXS_CREATE_MODULE()
|
||||
{"disable_sescmd_history", MXS_MODULE_PARAM_BOOL, "true"},
|
||||
{"max_sescmd_history", MXS_MODULE_PARAM_COUNT, "0"},
|
||||
{"strict_multi_stmt", MXS_MODULE_PARAM_BOOL, "true"},
|
||||
{"strict_sp_calls", MXS_MODULE_PARAM_BOOL, "false"},
|
||||
{"master_accept_reads", MXS_MODULE_PARAM_BOOL, "false"},
|
||||
{MXS_END_MODULE_PARAMS}
|
||||
}
|
||||
@ -275,6 +276,7 @@ static MXS_ROUTER *createInstance(SERVICE *service, char **options)
|
||||
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");
|
||||
router->rwsplit_config.strict_multi_stmt = config_get_bool(params, "strict_multi_stmt");
|
||||
router->rwsplit_config.strict_sp_calls = config_get_bool(params, "strict_sp_calls");
|
||||
router->rwsplit_config.disable_sescmd_history = config_get_bool(params, "disable_sescmd_history");
|
||||
router->rwsplit_config.max_sescmd_history = config_get_integer(params, "max_sescmd_history");
|
||||
router->rwsplit_config.master_accept_reads = config_get_bool(params, "master_accept_reads");
|
||||
@ -606,6 +608,8 @@ static void diagnostics(MXS_ROUTER *instance, DCB *dcb)
|
||||
router->rwsplit_config.retry_failed_reads ? "true" : "false");
|
||||
dcb_printf(dcb, "\tstrict_multi_stmt: %s\n",
|
||||
router->rwsplit_config.strict_multi_stmt ? "true" : "false");
|
||||
dcb_printf(dcb, "\tstrict_sp_calls: %s\n",
|
||||
router->rwsplit_config.strict_sp_calls ? "true" : "false");
|
||||
dcb_printf(dcb, "\tdisable_sescmd_history: %s\n",
|
||||
router->rwsplit_config.disable_sescmd_history ? "true" : "false");
|
||||
dcb_printf(dcb, "\tmax_sescmd_history: %d\n",
|
||||
@ -1187,6 +1191,10 @@ static bool rwsplit_process_router_options(ROUTER_INSTANCE *router,
|
||||
{
|
||||
router->rwsplit_config.strict_multi_stmt = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "strict_sp_calls") == 0)
|
||||
{
|
||||
router->rwsplit_config.strict_sp_calls = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "retry_failed_reads") == 0)
|
||||
{
|
||||
router->rwsplit_config.retry_failed_reads = config_truth_value(value);
|
||||
|
@ -272,6 +272,7 @@ typedef struct rwsplit_config_st
|
||||
bool master_accept_reads; /**< Use master for reads */
|
||||
bool strict_multi_stmt; /**< Force non-multistatement queries to be routed
|
||||
* to the master after a multistatement query. */
|
||||
bool strict_sp_calls; /**< Lock session to master after an SP call */
|
||||
enum failure_mode master_failure_mode; /**< Master server failure handling mode.
|
||||
* @see enum failure_mode */
|
||||
bool retry_failed_reads; /**< Retry failed reads on other servers */
|
||||
|
@ -146,6 +146,7 @@ bool is_read_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
void check_create_tmp_table(ROUTER_CLIENT_SES *router_cli_ses,
|
||||
GWBUF *querybuf, qc_query_type_t type);
|
||||
bool check_for_multi_stmt(GWBUF *buf, void *protocol, mysql_server_cmd_t packet_type);
|
||||
bool check_for_sp_call(GWBUF *buf, 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);
|
||||
|
||||
|
@ -134,9 +134,11 @@ bool route_single_stmt(ROUTER_INSTANCE *inst, ROUTER_CLIENT_SES *rses,
|
||||
succp = handle_master_is_target(inst, rses, &target_dcb);
|
||||
|
||||
if (!rses->rses_config.strict_multi_stmt &&
|
||||
!rses->rses_config.strict_sp_calls &&
|
||||
rses->forced_node == rses->rses_master_ref)
|
||||
{
|
||||
/** Reset the forced node as we're in relaxed multi-statement mode */
|
||||
/** Reset the forced node as we're in relaxed multi-statement
|
||||
* and SP call mode */
|
||||
rses->forced_node = NULL;
|
||||
}
|
||||
}
|
||||
@ -892,12 +894,14 @@ handle_multi_temp_and_load(ROUTER_CLIENT_SES *rses, GWBUF *querybuf,
|
||||
* 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_stmt(querybuf, rses->client_dcb->protocol, packet_type) ||
|
||||
check_for_sp_call(querybuf, packet_type)))
|
||||
{
|
||||
if (rses->rses_master_ref)
|
||||
{
|
||||
rses->forced_node = rses->rses_master_ref;
|
||||
MXS_INFO("Multi-statement query, routing all future queries to master.");
|
||||
MXS_INFO("Multi-statement query or stored procedure call, routing "
|
||||
"all future queries to master.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -355,6 +355,11 @@ bool check_for_multi_stmt(GWBUF *buf, void *protocol, mysql_server_cmd_t packet_
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool check_for_sp_call(GWBUF *buf, mysql_server_cmd_t packet_type)
|
||||
{
|
||||
return packet_type == MYSQL_COM_QUERY && qc_get_operation(buf) == QUERY_OP_CALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine the type of a query
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user