-
Type:
Improvement
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: Cache and Eviction, Statistics
-
None
-
Storage Engines - Transactions
-
182.808
-
SE Transactions - 2026-11-06
-
5
-
v9.0, v8.3, v8.0
Background
A refill asks for up to 100 pages to queue for eviction but often ends before it is full. Nothing says why. The possible reasons point at different work, and none of them is counted.
Statistics to add
Four counters, one per reason in the table. Each refill (a call of __wti_evict_lru_walk that gets past the early exit for full queues) adds one to the counter of the reason the last pass of the handle loop ended. The walk retries whole laps, up to 10, when it has not filled, so the last pass decides.
| Reason | Loop condition | Existing counter |
|---|---|---|
| filled | slot reaches max_entries | none |
| lap complete | loop count reaches the handle count | "eviction server completed walks of all dhandles": incremented where the handle iteration wraps; global, not tied to a refill, and a refill can wrap more than once |
| interrupted | the interrupt flag is set, EBUSY | none; the exit is swallowed (EBUSY becomes success) in __wti_evict_lru_walk without being counted |
| shutdown | closing or cache pool reconfiguring | none |
Notes:
- max_entries is also capped by the number of candidate pages in cache, so filled does not always mean 100 pages.
- Refills that exit early because both queues are full are already counted by the "queue not empty" statistic and are not among these.
- eviction_slow belongs to the outer pass loop and "eviction walks abandoned" is per tree; neither is a refill end reason.
Why this is worth doing
The dominant reason points at different work:
| Dominant reason | Meaning | Direction |
|---|---|---|
| interrupted | handle exclusive operations (handle close, sweep reclaim, a checkpoint gathering open handles) cut refills short | find who takes exclusive access and how often; reduce or batch the interrupts; faster scanning does not help |
| lap complete | every handle seen once and still short of the target: too few candidates | combine with the cache content distribution statistics (WT-18992) and the page skip reasons; reduce wasted visits or raise the yield per visit rather than scan faster |
| filled | each refill succeeds; supply is limited by how often refills happen | read the server time breakdown (WT-18993); cheaper skips and a bounded wake |
Limits: the counters say where the loop stopped, not why (who interrupts, why a lap finds too little). The share of interrupted refills is an upper bound on the gain of removing them, since filled refills take longer and the refill rate falls. Read the counters split by eviction mode (clean, dirty, update).
Definition of done
- The four counters add up to the number of refills that run the handle loop. Once WT-18993 lands, this can be checked against its refill count.
- A Python test makes each of the first three reasons happen and checks its counter moves: a workload with enough candidate pages (filled), many trees each with little to evict (lap complete), and a concurrent handle close during a refill (interrupted). The interrupted case may be hard to trigger deterministically; a timing stress or injection point is acceptable if stated in the test.
- Statistics described in stat_data.py (s_all clean).
- Backport to 8.0. The change is small and limited to the eviction server; the counters sit on the refill exit paths, and on 8.0 the code is in evict_lru.c.
- related to
-
WT-18829 Eviction candidate supply is capped when dirty content is spread across many trees (high data handle count)
-
- Open
-