[MXS-199] Support Causal Read in Read Write Splitting Created: 2015-06-15 Updated: 2018-09-19 Resolved: 2018-03-26 |
|
| Status: | Closed |
| Project: | MariaDB MaxScale |
| Component/s: | readwritesplit |
| Affects Version/s: | None |
| Fix Version/s: | 2.3.0 |
| Type: | New Feature | Priority: | Major |
| Reporter: | VAROQUI Stephane | Assignee: | markus makela |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||
| Description |
|
This is useful in a read-scaleout replication setup, where the application writes to a single master but divides the reads out to a number of slaves to distribute the load. In such a setup, an application could first do a write on the master, and then a bit later do a read on a slave, and if the slave is not fast enough, the data read from the slave might not include the update just made, possibly confusing the application and/or the end-user. The solution to address that issue is already available in MariaDB Maintain in maxscale a list of GTID apply to master but not yet receive by the slaves . just fecth gtid_binlog_pos in mariadb >= 10.0 When a read statement is routed on a slave, If timeout happen query should be routed to master or rerouted if the queuing take place on the slave . |
| Comments |
| Comment by markus makela [ 2015-09-01 ] | ||||
|
This could possibly be an improvement to the replication lag feature currently in use. It would be simpler and would not require MaxScale to create its own tables. | ||||
| Comment by VAROQUI Stephane [ 2015-09-01 ] | ||||
|
Can also be used to track old master status after a crash in case of slave promotion. For a failback or the old master reintroduction as slave in the cluster it is possible if the max gtid on old master is found on the new master before promotion. If not found on new master old master is mark desync in maxscale , and can be re provisioned using 10.2 new feature load data from master . https://mariadb.atlassian.net/browse/MDEV-7502 | ||||
| Comment by dapeng huang [ 2018-01-16 ] | ||||
|
maybe master_gtid_wait function can be implemented in hint, because add a query before every user query will be expensive, it will introduce a round trip latency; | ||||
| Comment by markus makela [ 2018-01-16 ] | ||||
|
Enabling MULTI_STATEMENTS and MULTI_RESULTS for the backend connections would allow this query:
To be converted into this:
This is how the GTID could be retrieved for later use. The SELECTS can then use this information to read from a consistent point. Here's an example:
To be converted into this:
The only problem with this is that we would need to discard the extra results returned by each query. This would also add extra overhead to the implementation but not a large one. Ideally, we would get the latest GTID in the OK packet that the server sends. With this, we would only need to modify SELECT statements (or even use some server-native mechanism to tell which GTID we want to use). In reality, we don't even need to have MULTI_STATEMENTS and MULTI_RESULTS enabled to allow multiple commands to be sent before any responses are received. This is due to the fact that the MariaDB server allows new queries to be sent even if previous ones have not yet been processed. | ||||
| Comment by VAROQUI Stephane [ 2018-01-17 ] | ||||
|
Optimistic fast prototype?
if empty query the master | ||||
| Comment by dapeng huang [ 2018-01-18 ] | ||||
|
It is not work if table `city` is empty | ||||
| Comment by VAROQUI Stephane [ 2018-01-23 ] | ||||
|
That's why it's optimistic, a long running empty query is something that can most of the time be fixed by proper indexing and for other cases should not stay in DBMS like a search engine ! so so 2 round trip for empty result can be fine for a fast prototype! | ||||
| Comment by dapeng huang [ 2018-01-24 ] | ||||
|
Maybe use MULTI_STATEMENTS is a good idea, but still have another problem:
No matter what the result of MASTER_GTID_WAIT is; the statements behind will be executed anyway; so if timeout do happened, we need discard all the results, it is so complicate and expensive. There is a tricky way to solve this problem:
When timeout, it will return error "ERROR 1242 (21000): Subquery returns more than 1 row", then we can redirect the query to master; | ||||
| Comment by markus makela [ 2018-03-26 ] | ||||
|
Implemented by the pull request by dapeng. Thank you for contributing! |