Severity: MEDIUM
Location: index/lsm/LSMTreeIndexCompactor.java:273 (throw ... "Root index page overflow"), :145-146/:188-189 (leaf pages flushed eagerly, no WAL), LSMTreeIndexCompacted.setCompactedTotalPages:532-537.
If compact() throws after leaf pages were flushed (root overflow, I/O error, interrupt), the series pages are on disk and the in-RAM page count was bumped, but page 0s series counter is untouched, so they are invisible - **until the next successful round**, because setCompactedTotalPages()publishesgetTotalPages(), which counts the orphans. Consequences: (a) stale duplicate entries become visible and re-expose tombstone/insert pairs; (b) a malformed partial series is walked by positional logic that assumes every leaf has a root entry; (c) if this was the first compaction (subIndex==null), the freshly registered compacted file (still TEMP_EXT`) is never linked nor dropped - the next round leaks another file.
Fix: wrap the merge in try/catch that truncates the compacted file back to its pre-round page count (or record the intended count in page 0 at round start and publish only that); drop the newly created compacted file if the creating round fails before splitIndex.
Filed from an internal engine deep-audit (2026-07). Traced to source; verify against current main before fixing and add a regression test.
Severity: MEDIUM
Location:
index/lsm/LSMTreeIndexCompactor.java:273(throw ... "Root index page overflow"),:145-146/:188-189(leaf pages flushed eagerly, no WAL),LSMTreeIndexCompacted.setCompactedTotalPages:532-537.If
compact()throws after leaf pages were flushed (root overflow, I/O error, interrupt), the series pages are on disk and the in-RAM page count was bumped, but page 0s series counter is untouched, so they are invisible - **until the next successful round**, becausesetCompactedTotalPages()publishesgetTotalPages(), which counts the orphans. Consequences: (a) stale duplicate entries become visible and re-expose tombstone/insert pairs; (b) a malformed partial series is walked by positional logic that assumes every leaf has a root entry; (c) if this was the first compaction (subIndex==null), the freshly registered compacted file (stillTEMP_EXT`) is never linked nor dropped - the next round leaks another file.Fix: wrap the merge in try/catch that truncates the compacted file back to its pre-round page count (or record the intended count in page 0 at round start and publish only that); drop the newly created compacted file if the creating round fails before
splitIndex.Filed from an internal engine deep-audit (2026-07). Traced to source; verify against current
mainbefore fixing and add a regression test.