Added configurable multistatement behavior

Whether all queries should be routed to the master after a multistatement
query is executed can now be controlled with the `strict_multi_stmt` option.

When the option is disabled queries executed after a multistatement query will
be routed normally.
This commit is contained in:
Markus Makela 2016-03-01 10:45:08 +02:00
parent ac007fa8f5
commit bf1a789376
4 changed files with 33 additions and 2 deletions

View File

@ -32,6 +32,12 @@ In master-slave replication cluster also read-only queries are routed to master
* statement includes a stored procedure, or an UDF call
If the client enables and executes multi-statements, they will be routed to
the master. All future queries will also be routed to the master to guarantee
a consistent session state after the multi-statement query. This behavior can
be controlled with the `strict_multi_stmt` router option. For more information,
read the [ReadWriteSplit](../Routers/ReadWriteSplit.md) router documentation.
### Limitations in client session handling
Some of the queries that client sends are routed to all backends instead of sending them just to one of server. These queries include `USE <db name>` and `SET autocommit=0` among many others. Readwritesplit sends a copy of these queries to each backend server and forwards the master's reply to the client. Below is a list of MySQL commands which are classified as session commands :

View File

@ -143,6 +143,22 @@ disable_sescmd_history=true
master_accept_reads=true
```
### `strict_multi_stmt`
When a client executes a multistatement query, all queries after that will be routed to
the master to guarantee a consistent session state. This behavior can be controlled with
the **`strict_multi_stmt`** router option. This option is enabled by default.
If set to false, queries are routed normally after a multistatement query. **Warning**, this
can cause false data to be read from the slaves if the multistatement query modifies
the session state. Only disable the strict mode if you know that no changes to the session
state will be made inside the multistatement queries.
```
# Disable strict multistatement mode
strict_multi_stmt=false
```
## Routing hints
The readwritesplit router supports routing hints. For a detailed guide on hint syntax and functionality, please read [this](../Reference/Hint-Syntax.md) document.

View File

@ -252,6 +252,8 @@ typedef struct rwsplit_config_st
int rw_max_sescmd_history_size;
bool rw_disable_sescmd_hist;
bool rw_master_reads; /*< Use master for reads */
bool rw_strict_multi_stmt; /*< Force non-multistatement queries to be routed
* to the master after a multistatement query. */
} rwsplit_config_t;
#if defined(PREP_STMT_CACHING)

View File

@ -696,7 +696,10 @@ createInstance(SERVICE *service, char **options)
*/
router->bitmask = 0;
router->bitvalue = 0;
/** Enable strict multistatement handling by default */
router->rwsplit_config.rw_strict_multi_stmt = true;
/** Call this before refreshInstance */
if (options)
{
@ -1384,7 +1387,7 @@ static route_target_t get_route_target(ROUTER_CLIENT_SES *rses,
target_t use_sql_variables_in = rses->rses_config.rw_use_sql_variables_in;
route_target_t target = TARGET_UNDEFINED;
if (rses->forced_node == rses->rses_master_ref)
if (rses->rses_config.rw_strict_multi_stmt && rses->forced_node == rses->rses_master_ref)
{
target = TARGET_MASTER;
}
@ -4640,6 +4643,10 @@ static void rwsplit_process_router_options(
{
router->rwsplit_config.rw_master_reads = config_truth_value(value);
}
else if(strcmp(options[i],"strict_multi_stmt") == 0)
{
router->rwsplit_config.rw_strict_multi_stmt = config_truth_value(value);
}
}
} /*< for */
}