[MDEV-16428] Simple concurrent DML on RocksDB tables makes optimistic parallel replication abort Created: 2018-06-07 Updated: 2023-04-27 |
|
| Status: | Confirmed |
| Project: | MariaDB Server |
| Component/s: | Replication, Storage Engine - RocksDB |
| Affects Version/s: | 10.2, 10.3, 10.4, 10.5 |
| Fix Version/s: | 10.4, 10.5 |
| Type: | Bug | Priority: | Major |
| Reporter: | Elena Stepanova | Assignee: | Sergei Petrunia |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||
| Description |
|
Note: run the test case below with --mysqld=--slave_parallel_mode=optimistic --mysqld=--slave-parallel-threads=2 --mysqld=--plugin-load-add=ha_rocksdb. It usually fails on the first attempt for me, but it's still a race condition, so sometimes it misses the mark. Run with --repeat if it doesn't fail right away.
Increasing rocksdb_lock_wait_timeout or slave_transaction_retries doesn't help, just makes the test run longer. |
| Comments |
| Comment by Sergei Petrunia [ 2018-06-18 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Full text of MTR failure: https://gist.github.com/spetrunia/a1f2a41144d0667a55d3afd7ad554cad | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-06-18 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re-starting the analysis. Debugging log:
Then, 0-1-7 is back?
It re-tries 10 times:
and then finally fails:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-06-19 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Yet another attempt to debug. Binlog events are:
Now, reading the debug log. Thread *04 executes the event with GTID 0-1-6:
Thread *04 starts to execute 0-1-7. It writes the first row into t2:
Thread *00 started to execute something (before this, it ran 0-1-3). We'll see a bit later that it's 0-1-8:
*04 continues, starts to write second row into t2:
Now we can see that thread 00 is executing 0-1-8. It deletes the first row. Note that this happens while 0-1-7 is still executing. This is how optimistic parallel replication works.
Thread 04 finishes writing the second row into t2:
Thread *00 continues to delete rows from t2, and reaches prepare stage:
Now, thred *04 is unable to get a lock on the row of t1 that it needs to modify:
It starts to retry but that will not succeed, as *00 is holding the locks on all rows in t1. Re-reading the text here https://mariadb.com/kb/en/library/parallel-replication/ :
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-06-20 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There is this function, thd_rpl_deadlock_check
which storage engine needs to call to inform the SQL layer that transaction X is about to wait on transaction Y. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-06-25 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
DRAFT Patch: https://github.com/MariaDB/server/commits/bb-10.2-mdev16428 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-06-25 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
thd_rpl_deadlock_check() function has a comment describing why the callback is needed and how it functions https://github.com/MariaDB/server/blob/10.3/sql/sql_class.cc#L4925 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-07-02 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The test tree is at: https://github.com/MariaDB/server/commits/bb-10.2-mdev16428 . Note that it uses a new submodule: rocksdb now refers to https://github.com/spetrunia/rocksdb/tree/mdev-16428 . | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Andrei Elkin [ 2020-10-01 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
My last comment offer of checking the table type and then degrade to conservative remains. If psergey does not have any better idea, let's go with that. |