Skip to content
/ server Public

Comments

MDEV-37974 Avoid bogus deadlock in lock_rec_insert_check_and_lock()#4672

Open
arcivanov wants to merge 1 commit intoMariaDB:10.11from
arcivanov:MDEV-37974
Open

MDEV-37974 Avoid bogus deadlock in lock_rec_insert_check_and_lock()#4672
arcivanov wants to merge 1 commit intoMariaDB:10.11from
arcivanov:MDEV-37974

Conversation

@arcivanov
Copy link
Contributor

@arcivanov arcivanov commented Feb 20, 2026

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.

@arcivanov arcivanov force-pushed the MDEV-37974 branch 3 times, most recently from 23599ab to d9e12c5 Compare February 20, 2026 07:25
@arcivanov arcivanov marked this pull request as draft February 20, 2026 08:16
@arcivanov arcivanov force-pushed the MDEV-37974 branch 2 times, most recently from c04ea78 to df10682 Compare February 20, 2026 08:20
@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label Feb 20, 2026
@arcivanov arcivanov force-pushed the MDEV-37974 branch 4 times, most recently from 081a437 to 0171d8d Compare February 22, 2026 02:21
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.
@arcivanov arcivanov marked this pull request as ready for review February 22, 2026 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

2 participants