ExportXMLWordPrintableJSON

    • Type: Improvement
    • Resolution: Unresolved
    • Priority: Trivial - P5
    • None
    • Affects Version/s: None
    • Component/s: Btree
    • None
    • Storage Engines - Transactions
    • 257.105
    • None
    • None

      Context

      WT-18565 (PR #14662) lets the cursor walk skip a clean in-memory internal page whose aggregate shows the whole subtree deleted and visible. After review, WT-18565 only skips on readonly stable checkpoint handles (WT_BTREE_READONLY and WT_URI_IS_STABLE_CHECKPOINT), which are immutable. This ticket tracks extending the skip to writable trees (e.g. the leader).

      Why the tree modified flag alone is not enough

      Proposal from review: skip when btree->modified is false. This is unsafe:

      • Checkpoint clears btree->modified at the start of __checkpoint_tree().
      • Dirty children are reconciled, and the parent's aggregate refreshed, only later in __wt_sync_file().
      • In between, the tree looks clean, a child leaf is still dirty with a new insert, and the parent's aggregate still says the subtree is deleted. A walk that trusts the flag skips the parent and misses the new record.

      Counter-example (reverted from the WT-18565 branch, kept for reference)

      Commit 0db26824c3 on branch wt-18565-allow-the-cursor-walk-to-skip-clean-in-memory-internal-pages:

      • New timing stress option checkpoint_sync_file_delay: pauses a user tree's checkpoint after btree->modified is cleared and bm->checkpoint_start() has run, before __wt_sync_file(); stat checkpoint_sync_file_stress_active marks the window.
      • Python case test_scan_while_checkpoint_clears_tree_modified in test_disagg_fast_truncate05.py and Catch2 test test_internal_skip_checkpoint.cpp.
      • With the skip check replaced by !btree->modified, both fail ((500, 'new value') not found). With child-state validation they pass.

      None of the existing checkpoint timing stress options pauses inside this window.

      Candidate approach

      Validate child state before skipping: scan the parent's ref array in both directions, reject a child that is pre-fetch queued, has dirty_state == WT_REF_DIRTY, or is not WT_REF_DISK/WT_REF_DELETED; then check the parent is not modified and re-read the aggregate. This was the original WT-18565 implementation.

      Review concern: the child scan is expensive. Counterpoint: it reads only in-memory refs (no page reads), stops at the first non-clean child, and runs only when the aggregate already says the subtree is deleted; not skipping costs a page read (a page service round trip in disagg) per on-disk child. Needs measurement before deciding.

      Review discussion

            Assignee:
            [DO NOT USE] Backlog - Storage Engines Team
            Reporter:
            Shoufu Du
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: