Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
24.02.4
-
None
Description
When using causal_reads MaxScale seems to get confused by the fact that INSERT INTO...RETURNING returns a resultset and doesn't update to the new GTID. Thus the next select has a wrong GTID inserted in the MASTER_GTID_WAIT prefix. This causes stale data to be returned to the client.
How to replicate:
- A simple primary-replica setup, 1 primary - 1 replica
- MaxScale 24.02.4 with `readwritesplit` and `causal_reads=global`
connect through maxscale and run
MariaDB [test]> drop database if exists test; create database test; create table test.test (id int); insert into test.test (id) values (1) returning 1; select count(*) from test.test; |
Query OK, 1 row affected (0.016 sec)
|
|
Query OK, 1 row affected (0.001 sec)
|
|
Query OK, 0 rows affected (0.004 sec) |
|
+---+ |
| 1 |
|
+---+ |
| 1 |
|
+---+ |
1 row in set (0.002 sec) |
|
+----------+ |
| count(*) | |
+----------+ |
| 0 |
|
+----------+ |
1 row in set (0.004 sec) |
Note how the final SELECT returned 0
As a contrast, when using a normal INSERT instead of the INSERT...RETURNING
MariaDB [test]> drop database if exists test; create database test; create table test.test (id int); insert into test.test (id) values (1); select count(*) from test.test; |
Query OK, 1 row affected (0.016 sec)
|
|
Query OK, 1 row affected (0.001 sec)
|
|
Query OK, 0 rows affected (0.005 sec) |
|
Query OK, 1 row affected (0.003 sec)
|
|
+----------+ |
| count(*) | |
+----------+ |
| 1 |
|
+----------+ |
1 row in set (0.004 sec) |
I have attached two logs , one with a normal insert and one with RETURNING.
You will notice how in the RETURNING case MASTER_GTID_WAIT is waiting on the last transaction before the INSERT instead of the INSERT itself.
I took the liberty to recompile maxscale so I could add 1 line of code in the `add_prefix_wait_gtid` function to log the actual GTID user in the `MASTER_GTID_WAIT` prefix. This makes the whole issue much easier to see.
This was specifically tested with `causal_reads=global` but most likely the problem exists with the other modes, too.
This was tested with 24.02.4, but most likely is an old bug that exists in many versions.
Attachments
Issue Links
- is blocked by
-
MDEV-36164 INSERT ... RETURNING doesn't return last_gtid in the system variable trackers
-
- Closed
-
So it turns out that I was wrong: the GTID for resultsets is only sent if the client uses the DEPRECATE_EOF protocol. When the client declares the capability, it is correctly returned. This needs to be added to the documentation as a limitation that mostly affects INSERT ... RETURNING.
I also did find a bug in readwritesplit where it doesn't look for the last_gtid variable if the result is classified as a resultset. This is probably why it didn't work in your case.