-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: Layered Tables
-
Storage Engines - Foundations
-
126.735
-
None
-
None
Summary
In disaggregated mode, the eviction server can retain a pointer to an obsolete shared history-store dhandle across role transitions. The shared dhandle can be replaced and freed while the eviction session still contains the old pointer.
Reproduction
Observed after the eviction server hits the shared-HS cursor cache and a role transition replaces the handle. The failure depends on the eviction server missing its next pass while sweep frees the old handle; no deterministic Python-only reproducer is included because this scheduling window requires control of the eviction thread.
Root cause
_wt_curhs_get_cached() calls _wt_cursor_cache_get() without WT_WITHOUT_DHANDLE. A cache-hit reopen assigns session->dhandle from the cached cursor. Closing the cursor pushes and pops API state, restoring that dhandle in the eviction-server session even though the session does not hold a reference to it. Across role transitions, the shared history-store dhandle can be replaced and the old handle freed while the session retains its pointer. On a follower, the leak is limited to the local history-store dhandle, which is not swept.
Expected behavior
The cursor-cache lookup must not leave the eviction server's session->dhandle pointing at a cached cursor's dhandle.
Fix
Wrap the cache lookup in WT_WITHOUT_DHANDLE so the eviction session's dhandle is restored after a cache-hit reopen.
Definition of Done
- The eviction server does not retain a stale shared history-store dhandle across role transitions.