Assert that removed-overflow cells never appear in the reconcile image

XMLWordPrintableJSON

    • Storage Engines - Transactions
    • 79.801
    • SE Transactions - 2026-06-05
    • 1

      Summary

      Add a diagnostic assertion in the upd == NULL path of __wti_rec_row_leaf that fires when an overflow cell marked as removed (WT_CELL_VALUE_OVFL_RM) would be written verbatim to the reconcile image.

      Background

      __wt_ovfl_remove changes the on-page cell type in-place from WT_CELL_VALUE_OVFL to WT_CELL_VALUE_OVFL_RM and frees the overflow block when a reconciliation replaces an overflow value. This is correct when the replacing update is committed and stable. When the replacing update is a prepared transaction that is later rolled back, the overflow block is gone but page->dsk still carries the stale marker. If the update chain is subsequently empty the copy-verbatim path copies 0xB0 (WT_CELL_VALUE_OVFL_RM) into the reconcile image, producing a corrupt on-disk page. The assertion turns this silent corruption into a deterministic crash in HAVE_DIAGNOSTIC builds.

      Crash evidence (format/RUNDIR.37 core dump)

      • btree->flags = 0 (regular file btree, maxleafvalue = 5120)
      • r->ovfl_items = true
      • r->newer_updates_than_last_rec_used = false
      • page->dsk + 312 = 0xB8 (WT_CELL_VALUE_OVFL_RM)
      • chunk->image.data + 0xE8 = same bytes (verbatim copy confirmed)
      • Crash in __rec_split_write at the WT_ASSERT that verifies the reconcile image

      Root cause

      The format test triggered the crash under timing_stress_for_test = [failpoint_eviction_split]. The assertion at rec_visibility.c:239 inside __rec_append_orig_value already enforces the same invariant from a different angle. The fix adds the complementary guard at the write site.

      Fix

      Added WT_ASSERT in __wti_rec_row_leaf (rec_row.c) before the copy-verbatim and overflow-repack paths:

      /*
       * A removed-overflow cell must never be written to disk: the backing block is already
       * gone so copying its in-memory marker verbatim produces a corrupt page image.
       */
      WT_ASSERT(session,
        !F_ISSET(vpack, WT_CELL_UNPACK_OVERFLOW) || vpack->raw != WT_CELL_VALUE_OVFL_RM);
      

      PR

      https://github.com/wiredtiger/wiredtiger/pull/13966

            Assignee:
            Chenhao Qu
            Reporter:
            Chenhao Qu
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: