Cache split (WT_PM_REC_MULTIBLOCK) results in the disaggregated victim cache

XMLWordPrintableJSON

    • Type: Improvement
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: Block Cache
    • None
    • Storage Engines - Persistence
    • 57.445
    • SE Persistence backlog
    • None

      Follow-up from WT-18626.

      Current state

      _evict_page_disagg_image() (evict_page.c) only resolves a cacheable image for a page whose reconciliation result is WT_PM_REC_REPLACE with a retained image, or a page never reconciled since being read. A page whose reconciliation result is WT_PM_REC_MULTIBLOCK (a split) always resolves to no image, so it is never cached: _evict_page_victim_cache_eligible() returns false and the page is discarded without publishing anything to the victim cache.

      This is safe — discarding is memory-clean (__free_page_modify() in bt_discard.c has a dedicated WT_PM_REC_MULTIBLOCK branch that frees every WT_MULTI entry's retained image, address, and block metadata) — but it means none of a split's new children get warmed into the cache, unlike a single-block replacement.

      Why this matters

      A page on an outdated disaggregated btree (a follower right after step-down) that reconciled into a split before the tree became outdated will have its split silently discarded rather than completed (_wt_split_multi()/wt_split_rewrite() are never called on that path — see the force-clean gate in _wt_evict()). Any of the split's children that were already durably written to shared storage get no warm entry in the local victim cache, so the first read of each child after step-down pays a full page-service round trip instead of a cache hit — the same class of cold-read cost the victim cache exists to avoid for the single-block case.

      What's involved

      Unlike a single-block replacement, a split produces multiple WT_MULTI entries, each with its own page_id/address and potentially its own retained disk_image. Caching them means:

      • Iterating mod->mod_multi (0..mod->mod_multi_entries) and calling plh_cache_put() once per entry that has a retained image and valid block metadata, instead of the current single-entry __evict_page_disagg_image() resolution.
      • Deciding what block metadata to publish per child, since page->disagg_info->block_meta describes the original (pre-split) page, not any individual child — each WT_MULTI entry's own block_meta (when populated) is likely the right source instead.
      • Confirming this is still gated correctly by the existing checkpoint-cursor, cold-tier, and page-log-availability checks in __evict_page_victim_cache_eligible(), which currently run once per page rather than once per child.

      Scope note

      This is a performance/warmth improvement, not a correctness fix — WT-18626 already ensures a split result is never cached under the wrong identity; it is just never cached at all. No urgency tied to a live incident.

            Assignee:
            [DO NOT USE] Backlog - Storage Engines Team
            Reporter:
            Chenhao Qu
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: