cockroachdb / cockroachdb/cockroach
kv: SKIP LOCKED skips keys with intents from committed transactions
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
The MVCC scanner's SKIP LOCKED path unconditionally skips keys with intents from other transactions without checking the intent's transaction status. This means intents from committed (or aborted) transactions are treated as held locks, causing SKIP LOCKED to skip rows that are not actually locked.
While this is not strictly a correctness issue — the intents will eventually be resolved and subsequent SKIP LOCKED scans will see the rows — it is undesirable behavior that can cause SKIP LOCKED to return fewer rows than expected.
For a normal (non-SKIP LOCKED) locking read, encountering an intent from another transaction triggers a push, which resolves the intent's transaction status and cleans up stale intents. SKIP LOCKED bypasses all of this machinery by design — the lock table scan is skipped, the MVCC scanner skips intents unconditionally, and post-scan intent resolution is async-only. This means the window between a transaction committing and its intents being resolved is a window where SKIP LOCKED skips those keys.
The metamorphic constant `max-intents-in-flight-per-caller` serializes intent resolution when set to 1, widening this window enough to cause flakes in the `select_for_share` logic test (#167458).
See also #165097, which describes the same underlying problem manifesting as spurious `lock_timeout` errors.
See also also #121917 for another real-world repro.
Jira issue: CRDB-62546
Epic CRDB-65887
Contributor guide
Assessment
This issue has not been assessed yet.