You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The existing TxIndex.Prune walks tx.height/* in lex order, which is NOT
numeric order for decimal-string heights. With a mix of digit widths
(e.g. "1000" sorting before "11"), the iterator can hit a high-numbered
height while many lower-numbered heights remain unprocessed and exit
via the keyHeight >= retainHeight early-break.
Repro: 1000 heights, retain=900 -> returns pruned=3 instead of 899.
PruneNumeric sidesteps this by iterating one height at a time with a
prefix-bounded Iterator(prefixKeyForHeight(h), nil) + bytes.HasPrefix
guard. Storage format unchanged; drop-in replacement.
Two further wins on top of correctness:
- Eliminates the 100k-key staging slice in Prune. Deletes go straight
into the batch (flushed every 1000), peak transient ~150 KB instead
of the multi-MiB staging pool. A/B at 100k blocks: d_heap drops from
+9 MiB to +0 MiB (flat), d_rss halves (+16 -> +8 MiB).
- Checkpoints lastRetainHeight after each batch flush, so a process
killed mid-cycle resumes from the last persisted height instead of
restarting at 1. Removes the 'perpetual re-bootstrap' failure mode
on long-running pruning workloads.
Trade: ~60% slower than Prune at 100k due to per-height iter open/close.
Worth it for correctness + bounded memory + resumability.
0 commit comments