fix(scorch): verify merge result integrity before introduction - #2389
Open
flash7777 wants to merge 1 commit into
Open
fix(scorch): verify merge result integrity before introduction#2389flash7777 wants to merge 1 commit into
flash7777 wants to merge 1 commit into
Conversation
Add a post-merge verification step that reads back the newly created segment before introducing it into the index snapshot. If any posting list entry is unreadable (e.g. corrupt varint encoding), the merge result is discarded and the source segments are preserved. This prevents corrupt segments from entering the index, where they would cause permanent read errors and eventually block the merger goroutine entirely. We observed sporadic corruption (~1% of merges) in merge result segments when merging segments that contain document drops (updates). The corruption manifests as ReadUvarint overruns in freq/norm data. Without this guard, one corrupt merge result permanently blocks the merger (it retries the same segment combination indefinitely). With it, corrupt results are discarded, the merger retries with a different segment combination, and the index remains correct. Applied in both merge paths: - planMergeAtSnapshot (file merge, merger goroutine) - mergeAndPersistInMemorySegments (in-memory merge, persister goroutine) The verification cost is one sequential read of the merge result. For typical merges (2-4 segments, a few thousand documents), this is 1-10ms against 100-1000ms for the merge itself (<10% overhead). Relates to blevesearch#1306
flash7777
force-pushed
the
fix/verify-merge-result
branch
from
August 10, 2026 14:13
3d0b880 to
eaee180
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a post-merge verification step that reads back the newly created segment before introducing it into the index snapshot. If any posting list entry is unreadable (e.g. corrupt varint encoding), the merge result is discarded and the source segments are preserved.
This prevents corrupt segments from entering the index, where they would cause permanent read errors and eventually block the merger goroutine entirely.
Background
We observed sporadic corruption (~1% of merges) in merge result segments when merging segments that contain document drops (updates/deletes). The corruption manifests as
ReadUvarintoverruns in freq/norm data — the segment file has the correct size but contains unreadable varint sequences.Key observations:
MergeUsing— no external mutation; the bug is in the merge write path itselfWhat this PR does
After
segPlugin.MergeUsing()+segPlugin.OpenUsing(), iterate every posting of every term of every field in the new segment. If anyIterator.Next()returns an error, discard the segment file and return an error from the merge task. The source segments remain in the index unchanged.Applied in both merge paths:
planMergeAtSnapshot(file merge, merger goroutine)mergeAndPersistInMemorySegments(in-memory merge, persister goroutine)Performance
The verification reads the merge result sequentially once. For typical merge tasks (2-4 segments, a few thousand documents), this takes 1-10ms against 100-1000ms for the merge itself (<10% overhead).
Reproduction
MimeType="application/pdf")Environment: bleve v2.6.0, zapx v17, Go 1.24, 68k documents.
Related