MDEV-37974 Avoid bogus deadlock in lock_rec_insert_check_and_lock()#4672
Open
arcivanov wants to merge 1 commit intoMariaDB:10.11from
Open
MDEV-37974 Avoid bogus deadlock in lock_rec_insert_check_and_lock()#4672arcivanov wants to merge 1 commit intoMariaDB:10.11from
arcivanov wants to merge 1 commit intoMariaDB:10.11from
Conversation
23599ab to
d9e12c5
Compare
c04ea78 to
df10682
Compare
081a437 to
0171d8d
Compare
When a transaction holds a granted lock on a record and another transaction is waiting for that same record, an `INSERT` by the lock-holding transaction into the gap before that record would incorrectly enter `lock_wait()` on the waiting lock, creating a false deadlock cycle. In `lock_rec_insert_check_and_lock()`, after `lock_rec_other_has_conflicting()` returns a conflicting lock, check whether: 1. the conflicting lock is **WAITING**, 2. we hold a **granted** lock on the same record, and 3. no other transaction holds a **GRANTED** lock that conflicts with our `INSERT_INTENTION`. Only skip the lock wait when all three conditions are met. The scan for granted conflicting locks is needed because lock inheritance during purge can create granted `GAP` locks from other transactions that coexist with our `LOCK_ORDINARY` but still block `INSERT_INTENTION`. The bogus deadlock in `lock_delete_updated` and `versioning.update` (MDEV-14829 section) is also eliminated. In `lock_delete_updated`, the `DELETE` no longer deadlocks but the row at the new PK position is missed by the forward scan (pre-existing behavior). In `versioning.update`, the concurrent `UPDATE` on a system-versioned table no longer deadlocks because the historical row `INSERT` correctly skips the waiting lock.
0171d8d to
a99f1e0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a transaction holds a granted lock on a record and another
transaction is waiting for that same record, an
INSERTby thelock-holding transaction into the gap before that record would
incorrectly enter
lock_wait()on the waiting lock, creating afalse deadlock cycle.
In
lock_rec_insert_check_and_lock(), afterlock_rec_other_has_conflicting()returns a conflicting lock,check whether:
with our
INSERT_INTENTION.Only skip the lock wait when all three conditions are met. The scan
for granted conflicting locks is needed because lock inheritance
during purge can create granted
GAPlocks from other transactionsthat coexist with our
LOCK_ORDINARYbut still blockINSERT_INTENTION.The bogus deadlock in
lock_delete_updatedandversioning.update(MDEV-14829 section) is also eliminated. In
lock_delete_updated,the
DELETEno longer deadlocks but the row at the new PK positionis missed by the forward scan (pre-existing behavior). In
versioning.update, the concurrentUPDATEon a system-versionedtable no longer deadlocks because the historical row
INSERTcorrectly skips the waiting lock.