-
Type:
Bug
-
Resolution: Cannot Reproduce
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Not Applicable
-
None
-
Storage Engines - Transactions
-
2,294.154
-
SE Transactions - 2026-07-03, SE Transactions - 2026-07-17, SE Transactions - 2026-07-31
-
3
-
Not Needed
Summary
__evict_push_candidate CAS'd the WT_PAGE_EVICT_LRU flag without holding evict_queue_lock. A walker thread could observe WT_REF_MEM, be preempted, then set WT_PAGE_EVICT_LRU on a ref that another thread had already transitioned to WT_REF_LOCKED and fully evicted — the active evictor had already cleared the flag. The discarded page then trips the assertion in __wt_page_out.
Impact
Assertion trip under concurrent eviction + split workloads. Reproducible under test/format stress. Affects develop generally.
File
- src/evict/evict_lru.c
Fix
Assert evict_queue_lock is held inside __evict_push_candidate, re-check ref state under the lock, and acquire it at the call site in __evict_try_queue_page:
// src/evict/evict_lru.c — __evict_push_candidate +WT_ASSERT_SPINLOCK_OWNED(session, &S2C(session)->evict->evict_queue_lock); +if (WT_REF_GET_STATE(ref) != WT_REF_MEM) return (false); // src/evict/evict_lru.c — __evict_try_queue_page call site -if (!__evict_push_candidate(session, queue, evict_entry, ref)) +__wt_spin_lock(session, &evict->evict_queue_lock); +bool pushed = __evict_push_candidate(session, queue, evict_entry, ref); +__wt_spin_unlock(session, &evict->evict_queue_lock); +if (!pushed) return;
Notes
Discovered during development on the WT-16973 clean-scrub eviction branch (PR #13605). The fix is independent of that feature and should be applied directly to develop.
- is related to
-
WT-18164 Investigate relaxing the single eviction-queue-membership requirement
-
- Closed
-