-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: Layered Tables
-
None
-
Storage Engines - Transactions
-
206.904
-
SE Transactions - 2026-10-23
-
3
Problem
A prepare conflict on a btree cursor leaves the cursor positioned on the conflicting key, so reversing direction returns the last key it returned again. The diagnostic key-order check skips that return, but also does not record it, so the state it compares against is stale. If the walk's own transaction has inserted a key between the last returned key and the conflicting one, the reversal returns that key first, and the next return is flagged as out of order:
WT_CURSOR.prev out-of-order returns: returned key 3 then key 3
followed by a panic in diagnostic builds. This is a diagnostic false positive on valid output, but it aborts the process.
Reproducer (plain btree table, no layered tables)
- Table with committed keys 1, 2, 3.
- Another session inserts key 5 and prepares.
- In a snapshot transaction, walk with next: 1, 2, 3, then a prepare conflict at 5.
- In the same transaction, insert key 4 through another cursor.
- Walk with prev: 4, then 3 trips the key-order check. The mirror case (prev then next) fails the same way.
Fix
In _wt_btcur_next and _wt_btcur_prev, restart the key-order check when the cursor reverses out of a prepare conflict (and on a read-uncommitted page crossing), then check the key it returns, so the returned key is recorded. Previously the check was skipped entirely. This is found as part of WT-18717, where the layered cursor reverses out of a prepared conflict on a constituent btree cursor.