-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: History Store, Transactions, Truncate
-
None
-
Storage Engines - Transactions
-
114.901
-
None
-
None
Summary
WT-10013's guard in _wti_delete_page() (bt_delete.c) limits an untimestamped fast truncate to pages whose content is globally visible, specifically to avoid orphaning real-timestamped history-store rows that fast truncate cannot clear (fast truncate never visits individual keys, so it never runs the per-key clear that an ordinary tombstone would trigger via rec_hs_handle_oldest_tombstone() / _wti_rec_hs_delete_key()).
That guard checks the page's aggregate time window (addr.ta.newest_start_durable_ts / newest_stop_durable_ts), not each entry individually. A page can be "globally visible" in aggregate while mixing two kinds of content: keys already deleted by an earlier, ordinary, real-timestamped remove (which left real superseded history behind in the history store), and keys that are still live. The guard does not distinguish this mixed case from a page that was always uniformly live – both pass once oldest_timestamp has advanced far enough.
When an untimestamped (no_timestamp=true) fast truncate covers such a mixed page, the already-deleted key's own legitimate, real-timestamped history-store entry is left behind uncleaned, exactly as in the uniform case WT-10013 was written to prevent. Unlike a page that's merely stale-but-still-reachable (ordinary HS cleanup is lazy and only runs when the owning data page is next reconciled), this key's tombstone cell no longer exists anywhere in the live tree once the page becomes WT_REF_DELETED/page_del – there is no future reconciliation event left that could ever discover and clean the entry. It survives permanently, without needing write_timestamp_usage to be altered or any other unusual configuration: this reproduces on an ordinary, default-policy table under plain timestamped application traffic.
This is a narrower-triggering sibling of WT-18551 (which requires write_timestamp_usage=never): here the WT-10013 gate is fully engaged and working as designed, and is still insufficient, because it reasons about the page in aggregate rather than per key.
Reproduction
1. Create a table with the default write_timestamp_usage policy.
2. Write key K at ts=10, overwrite it at ts=20 (moves the ts=10 value to the history store under a real [10,20) window), then delete K with a real timestamp at ts=30. Write ~500 other keys, left live, on the same/neighboring pages.
3. Checkpoint, evict (without closing the connection – closing marks it shutting down, at which point everything is treated as globally visible and clears the history store regardless of the bug).
4. Advance oldest_timestamp to 30 – ordinary housekeeping, no special configuration.
5. Begin an ordinary transaction with no_timestamp=true, truncate a range spanning K and the live keys, commit. The commit succeeds, rec_page_delete_fast increments (fast path ran), cache_hs_key_truncate stays flat (no per-key clear ran).
6. Checkpoint again. K's [10,20) history-store entry is still present.
A control (identical setup, no truncate, several checkpoints instead) also shows the entry persisting – ordinary HS cleanup is lazy in general, so persistence alone isn't proof of a bug. The distinguishing factor is that in the control, K's tombstone cell still physically exists on a live, reachable page, so a later reconciliation of that page can still discover and clean the history-store entry. In the truncate case, that page/cell no longer exists in the live tree at all once it becomes page_del-deleted, so no such future cleanup opportunity remains.
Notes
- No fix is proposed yet. The
WT-10013gate would need to reason about whether any entry on the page has real, non-obsolete timestamped history that fast truncate would strand, not just the page's aggregate visibility – or fast truncate would need to fall back to the slow path whenever such mixed content is present. - Related:
WT-18551(the write_timestamp_usage=never variant of essentially the same underlying gap, where theWT-10013gate is bypassed entirely rather than merely insufficient). - Not related to the currently-reverted
WT-18300mixed-mode timestamp-usage-check work; this is a pre-existing, independent gap in the originalWT-10013guard itself.
- is related to
-
WT-10013 Fast truncate without a timestamp doesn't clear the history store
-
- Closed
-
-
WT-18551 Altering write_timestamp_usage to never bypasses the fast-truncate history-store guard from WT-10013
-
- Closed
-
-
WT-18300 failed: model-test-long-disagg on amazon2023-arm64 [wiredtiger @ 2dc4d9b8]
-
- Closed
-