-
Type:
Improvement
-
Resolution: Fixed
-
Priority:
Major - P3
-
Affects Version/s: None
-
Component/s: Page deltas
-
None
-
Storage Engines, Storage Engines - Transactions
-
0.001
-
SE Transactions - 2026-06-19
-
None
Summary
During leaf page delta construction, __wti_rec_pack_delta_row_leaf claimed two scratch buffers — key and custom_value — on every changed key and released them before returning. For a page with N changed keys, this produced 2N scratch pool claim/release cycles per delta reconciliation.
Root Cause
The two buffers were declared as function-local scratch items:
WT_DECL_ITEM(custom_value);
WT_ITEM *key;
...
WT_ERR(__wt_scr_alloc(session, 0, &key));
WT_ERR(__wt_scr_alloc(session, custom_value_size, &custom_value));
...
err:
__wt_scr_free(session, &key);
__wt_scr_free(session, &custom_value);
There was no functional reason for either buffer to have per-key lifetime. Both are write-only intermediates — key holds the extracted key bytes for cell building, and custom_value holds the packed [flags | value_data] blob for the value cell — neither value needs to survive the iteration.
Fix
Lift both allocations to __rec_build_delta_leaf, the caller that owns the loop. The buffers are claimed once before the loop and freed once in the err: label. __wti_rec_pack_delta_row_leaf receives them as WT_ITEM * parameters. Between iterations custom_value is reset via __wt_buf_init, which is two pointer assignments and a size comparison when the buffer is already large enough.
Impact
Reduces scratch pool operations from 2N to 2 per delta build, where N is the number of changed keys on the page. The scratch pool scan is O(pool slots), so the saving is proportional to write pressure on hot pages with many concurrent updates.
Files to be changed
- src/reconcile/rec_row.c — updated __wti_rec_pack_delta_row_leaf signature; removed per-call alloc/free
- src/reconcile/rec_write.c — updated __rec_build_delta_leaf to own and reuse the scratch buffers
- src/reconcile/reconcile_private.h — updated prototype
- related to
-
WT-17840 s_all errors due to unpinned clang-format version
-
- Closed
-