OceanBase Database maintains the waiting relationships between locks in memory. When a lock is released, it wakes up the transactions waiting on the lock.
The lock wait manager maintains the waiting relationships between rows and transactions in memory and wakes up the waiting transactions to retry when a lock is released. The wake-up operation may be triggered by the end of a transaction, a SAVEPOINT rollback, or an early unlock.
Types of lock waiting relationships
In the lock wait manager, there are three types of lock waiting relationships: row locks, table locks, and transaction locks.
Row lock waiting relationship
A row lock waiting relationship is a regular data waiting relationship. When a row lock is released, the system wakes up the first transaction in the waiting queue to retry.
Table lock waiting relationship
A table lock waiting relationship is similar to a row lock waiting relationship, but the conflict is based on table-level locking. A table lock affects all operations on the table.
Transaction waiting relationship
To reduce memory usage, row lock waiting relationships are converted to transaction waiting relationships in scenarios such as a dump. When a transaction ends, the system wakes up all other transactions waiting on the transaction.
Establishment of lock waiting relationships
Local establishment
For example, when different transactions lock the same row lock and create a mutual exclusion, the system collects the conflict information, such as the lock time, the hash value of the locked row, the ID of the holding transaction, and the ID of the locking transaction. The system also records the sequence value of the corresponding Lock Wait Mgr bucket at this time. This value corresponds to the bucket and increments by 1 when the hash value mapped to this bucket is released. After the lock fails, the transaction rolls back the statement and enters the corresponding bucket to wait for the lock. Before entering the bucket, the system compares the recorded sequence value with the current sequence value of the bucket to determine whether the lock has been released. If the sequence value has changed, the transaction immediately retries the request without entering the waiting queue. Otherwise, it enters the queue to wait for the lock.
As shown in the preceding figure, when transaction 3 encounters a lock conflict and attempts to enter the bucket to wait for the lock, if the recorded sequence value is 1 and the current sequence value of the bucket has changed to 2, it indicates that the lock resource was released before entering the waiting queue. In this case, transaction 3 immediately retries the request without entering the waiting queue. If the sequence value of the bucket remains 1, transaction 3 enters the bucket to wait for the lock.
The lock waiting relationships described above are established when the observer node that processes the transaction statement request (the control node) and the execution node that generates the lock conflict are the same.
Remote establishment
For remote execution, the establishment of waiting relationships is more complex. When a conflict occurs during remote execution, the system collects the conflict information and sends it back to the control node. The control node then enters the corresponding Lock Wait Mgr bucket to wait for the lock. Since the waiting row is not on the current node, the execution node also enters the Lock Wait Mgr bucket to wait for the lock. The purpose of this is to detect the lock release and remotely notify the control node to retry the request. When the lock is released, the system remotely wakes up the control node from the waiting queue to retry the request. To prevent the loss of remote wake-up operations due to network issues or node failures, the system has a regular probing mechanism. The transaction waiting at the control node periodically probes the status of the execution node. If an exception is detected, the system removes the transaction from the queue and retries the request.
Maintenance of lock waiting relationships
In fact, the lock wait manager maintains a fixed number of buckets in a hash map. Based on the hash mapping result, the system links the waiting transactions in a linked list to the corresponding bucket. When a lock is released, the system simply removes the corresponding transaction from the hash bucket and retries the request.
As shown in the preceding figure, transaction 2 is waiting for a lock on Bucket N-1. When transaction 3's row lock is released and its hash value maps to Bucket N-1, the system traverses the waiting transactions on Bucket N-1 to find a transaction with the same hash value as the row and removes it to retry the request. This approach avoids false wake-ups when different hash values map to the same bucket. When a transaction waiting relationship is established, if the transaction's hash value maps to bucket 3, both transaction 1 and transaction 4 will be woken up to retry the request.
