WL#6363: InnoDB: implement SX-lock for rw_lock
Status: Complete
InnoDB internally uses rw-lock implementation to keep consistency of internal resources. Basically the rw-lock has 2 types S-lock (shared) and X-lock (exluded). The fix adds the new type SX-lock (shared excluded) for room to optimize concurrency and improve scalability more. At least, S-lock and X-lock behave same, and compatible for current code. So, nothing changed by only this fix as it is. (no functional/performance changes for users) The new state SX-lock will be used by the future work. (e.g. WL#6326: InnoDB: fix index->lock contention)
(1) new state of rw_lock: SX-lock
| S|SX| X|
--+--+--+--+
S| o| o| x|
--+--+--+--+
SX| o| x| x|
--+--+--+--+
X| x| x| x|
--+--+--+--+
Though it can be equivalent to 2 rw-locks (S=S1 SX=S1+X2 X=X1),
the increasing atomic instructions should make more expensive, so chosen
SX-lock for now.
The recursive obtaining of the SX-lock is allowed when has only X or SX or
both of them.
*Obtaining X-lock on SX-lock is allowed, but it treated as new lock and should
obey to latching order.
The operation to relax the X-lock to SX-lock should be supported.
(not need special function if implemented "sx-lock;x-unlock" as 1 atomic
operation)
***inaam: Can you add more details about recursive locking? It is not very clear
as it stands right now.
Also can you please add some low level details about the core parts like changes
to lock_word, dealing with recursion and how is integrity maintained of other
flags in the rw-lock.
***yasufumi: Currently no limitation about recursive locking about X (not
changed) and SX (also). But we should careful about X lock on SX lock. It should
be check as new lock because upgrading.
- X_LOCK_HALF_DECR defined as X_LOCK_DECR/2
- (volatile lint)(lock->sx_recursive) added to count sx-locks
- lock->writer_thread is used also for sx-locks, because exclusive each other
among x and sx.
- lock->lock_word represents state as followings
------------------------------------------------------------------------------
lock_word == X_LOCK_DECR Unlocked
X_LOCK_HALF_DECR < lock_word < X_LOCK_DECR S locked.
No waiting writers.
(X_LOCK_DECR - lock_word) is the
number of readers that hold the lock.
lock_word == X_LOCK_HALF_DECR SX locked
Waiting writers not allowed
0 < lock_word < X_LOCK_HALF_DECR SX locked AND S locked
(X_LOCK_HALF_DECR - lock_word)
is the number of readers i.e.: S locks
No waiting writers allowed
lock_word == 0 X locked
No waiting writers allowed
-X_LOCK_HALF_DECR < lock_word < 0 S locked with a waiting writer
-lock_word is the number of
readers i.e.: S locks
lock_word == -X_LOCK_HALF_DECR X lock + recursive SX lock
No waiting writers allowed
-X_LOCK_DECR < lock_word < -X_LOCK_HALF_DECR S locked with a waiting writer
which has SX-lock
-(lock_word + X_LOCK_HALF_DECR)
is the number of readers i.e.: S locks
lock_word == -X_LOCK_DECR X lock + recursive X lock i.e.:
2X locks
-(X_LOCK_DECR + X_LOCK_HALF_DECR) < lock_word < -X_LOCK_DECR
(2 - (lock_word + X_LOCK_DECR))X
locks
lock_word == -(X_LOCK_DECR + X_LOCK_HALF_DECR) 2X locks + SX lock
lock_word < -(X_LOCK_DECR + X_LOCK_HALF_DECR) (2 - (lock_word + X_LOCK_DECR +
X_LOCK_HALF_DECR))X locks
+ SX lock
------------------------------------------------------------------------------
Copyright (c) 2000, 2025, Oracle Corporation and/or its affiliates. All rights reserved.