[MDEV-21574] MyRocks: Range Locking: RCU-based cache for the root node Created: 2020-01-27 Updated: 2020-04-06 |
|
| Status: | Open |
| Project: | MariaDB Server |
| Component/s: | Storage Engine - RocksDB |
| Fix Version/s: | N/A |
| Type: | Task | Priority: | Major |
| Reporter: | Sergei Petrunia | Assignee: | Sergei Petrunia |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Attachments: |
|
||||||||||||
| Issue Links: |
|
||||||||||||
| Description |
| Comments |
| Comment by Sergei Petrunia [ 2020-01-27 ] | ||||||||||||||||||||||||||||||||||||
|
A question: how expensive is the synchronize_rcu call ? AFAIU, It does O(#active_threads) operations. Does it wait or spin if it finds a reader that's not done? (EDIT: most likely, it walks through the list of "active" threads and sees if any of them is in the read lock section. If it is, it spins until it is done) | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-02-08 ] | ||||||||||||||||||||||||||||||||||||
|
Update (posting late): First implementation of RCU-based cache: rcu4a.diff The first benchmark results results-feb3.tgz
| ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-02-08 ] | ||||||||||||||||||||||||||||||||||||
|
First candidate reason: the locktree seems to be often unbalanced at the root node. | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-02-10 ] | ||||||||||||||||||||||||||||||||||||
|
Added a counter to check how often the root is observed to have just one child.
| ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-02-10 ] | ||||||||||||||||||||||||||||||||||||
|
Added rotations. Now, if the root node has one child and the other one with depth > 3, a rotation will be performed so that the root node has two children. | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-02-10 ] | ||||||||||||||||||||||||||||||||||||
|
... This didn't help. Still, counters show a picture like this:
One can see that only a very small fraction of lock acquire operations used the RCU. For lock releases, the situation is similar, although RCU is used more (not sure why):
| ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-02-10 ] | ||||||||||||||||||||||||||||||||||||
|
RANGELOCK_EXTRA_COUNTER3 here counts the number of times the code examined m_rangetree->rcu_cache_usable, found it to be FALSE, and didn't use the RCU. The issue is, current code works like so: if we can't use the RCU codepath, we take the non-RCU one (where we acquire the mutex). Could the following be happening: one thread needs to use non-RCU codepath on the root node (e.g. it is releasing the lock that is in the root node). Others start waiting, upon finishing their wait they take the non-RCU code path, too. This causes yet more threads to fail to use RCU code path and wait, and so forth... | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-03-15 ] | ||||||||||||||||||||||||||||||||||||
|
Finally managed to get rid of crashes/corruption in the "improved" RCU code. Pushed it here: https://github.com/spetrunia/mysql-5.6/tree/range-locking-fb-mysql-5.6.35-rcu | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-03-15 ] | ||||||||||||||||||||||||||||||||||||
|
c5.2xlarge:
| ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-03-16 ] | ||||||||||||||||||||||||||||||||||||
|
This shows RCU now is much more commonly used, but the %age of the operations that use the RCU is still too low. Questions:
| ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-03-17 ] | ||||||||||||||||||||||||||||||||||||
|
Could it be that my idea about how often the root node needs to be modified is wrong? no surprises so far... | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-03-30 ] | ||||||||||||||||||||||||||||||||||||
|
Improved patch, run in c5.9xlarge (two runs with the patch, one without perf counters and one with):
It is not as bad as before, but still it's worse than regular range locking | ||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-03-30 ] | ||||||||||||||||||||||||||||||||||||
|
Counters for the new patch: https://docs.google.com/spreadsheets/d/1aApVWcYp9CogAUfho9wvH55-h4a0SkdKFAqJFNXQku0/edit#gid=0 At high number of threads, the number of operations that use the RCU read path (and don't acquire mutex on the root node) is about 90%. With previous patch, it was 50-70%. If an operation (lock acquisition/release) couldn't use the RCU read path, it will get the root node's mutex. Then, it will examine the root node and arrive at one of these outcomes:
One can see that RCU_DISABLE_DUE_TO_REBALANCE is relatively rare. |