GITHUB#7820: report which segment's .si could not be read - #16476
Open
serhiy-bzhezytskyy wants to merge 4 commits into
Open
GITHUB#7820: report which segment's .si could not be read#16476serhiy-bzhezytskyy wants to merge 4 commits into
serhiy-bzhezytskyy wants to merge 4 commits into
Conversation
…o (_N.si) file in CheckIndex (cherry picked from commit 4c5c628) (cherry picked from commit 2c33c716f81eebe3c305bb88150d465790f7ccd3)
Follow-up to the previous commit, which is @gokaai's from apache#12872, rebased onto main. That PR introduced CorruptSegmentInfoException but did not finish the two things asked for in its review, so nothing downstream could use the exception: - The throw site caught the codec's failure and dropped it, passing the 3-arg constructor. Mike McCandless asked on the PR: "Can we somehow return the root cause exception here and include it in CheckIndexException". The cause is what names the file on disk (NoSuchFileException carries the full path to _1.si, a truncated .si surfaces as an EOFException naming the MemorySegmentIndexInput), so dropping it discards the only concrete detail available. - segmentName was package-private with no accessor, so no caller outside org.apache.lucene.index could read it, and no test could assert on it. Changes: - CorruptSegmentInfoException keeps one constructor rather than six, requires a non-null segmentName and cause, and exposes getSegmentName(). - SegmentInfos passes the cause, and catches Exception | AssertionError rather than Exception, per the review comment that corruption in a .si "can result in exotic exceptions". IOContext.READONCE is main's, kept over the PR's READ. - CheckIndex records the name in Status#brokenSegmentName and reports it, so the message says which segment is broken instead of only that a commit point was unreadable. - TestCheckIndex#testCorruptSegmentInfoNamesTheSegment covers both a deleted and a truncated .si, asserting the segment name, the cause type, and that the cause names _1.si. apache#12872 had no test for the exception it added.
This was referenced Aug 2, 2026
Member
|
Thank you for resurrecting this dying-on-the-vine PR @serhiy-bzhezytskyy! |
mikemccand
approved these changes
Aug 4, 2026
mikemccand
left a comment
Member
There was a problem hiding this comment.
This looks great -- thank you @gokaai and @serhiy-bzhezytskyy for renewing this long ago and important improvement to our corrupt index messaging! I left small polish comments; I think this is otherwise ready.
Is it backportable to 10.x?
|
|
||
| final Version version = info.info.getVersion(); | ||
| if (info.info.maxDoc() <= 0) { | ||
| throw new CheckIndexException(" illegal number of documents: maxDoc=" + info.info.maxDoc()); |
Member
There was a problem hiding this comment.
Thank you for the clean-as-you-go.
|
|
||
| long totalDocs = 0; | ||
|
|
||
| SegmentInfo info; |
Member
There was a problem hiding this comment.
Could we move this inside the for loop, just above the new try {? (Shrink-wrap the scoping)
| if (!e.getMessage().contains("on purpose")) { | ||
| throw e; | ||
| // Caught "on-purpose" IOException can be rethrown as CorruptSegmentInfoException | ||
| if (!(e instanceof CorruptSegmentInfoException)) { |
Signed-off-by: Serhiy Bzhezytskyy <me@serhiy-bzhezytskyy.com>
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.
Description
CheckIndexreports that a commit point could not be read, but not which segment is at fault:The information exists at the point of failure — a deleted
.siarrives as aNoSuchFileExceptioncarrying the full path, a truncated one as a suppressedEOFExceptionnaming theMemorySegmentIndexInput— butSegmentInfos#parseSegmentInfoslets the codec's exception propagate untyped, so nothing downstream can tell which segment it was. This is the November 2023 comment on #7820:After this change:
Changes
The first commit is @gokaai's from #12872, rebased onto
mainwith authorship intact. It introducesCorruptSegmentInfoExceptionand throws it fromSegmentInfoswhen a segment's.sicannot be read. Two hunks needed adjusting formain:IOContext.READbecameIOContext.READONCE, and the wildcard import was replaced with explicit ones, which the ecj lint requires.The second commit finishes the two things asked for in that PR's review but not done there:
CheckIndexException". It is now passed, and the catch isException | AssertionErrorrather thanException, per the same review: "Corruption in.sican result in exotic exceptions".segmentNamewas unreachable. It was package-private with no accessor, so nothing outsideorg.apache.lucene.indexcould read the name the exception exists to carry, and no test could assert on it.getSegmentName()is added, the six constructors are reduced to the one that is used, and both arguments areObjects.requireNonNull.On top of that,
CheckIndexrecords the name inStatus#brokenSegmentNameand puts it in the message, andTestCheckIndex#testCorruptSegmentInfoNamesTheSegmentcovers a deleted and a truncated.si, asserting the segment name, the cause's type, and that the cause names_1.si. #12872 had no test for the exception it added.Relationship to #12872 and #16474
#12872 has been open since 2023-12 and is no longer mergeable; the last human comment there is from 2024-02, after a
gitdigression, and @mikemccand's "I'll try to review soon!" never got a follow-up. The pain it addresses is still there, so this carries it forward rather than leaving it. If @gokaai would rather finish it there, close this one — the point is the fix landing, not where.#16474 is the other half of the same thread:
exorciseIndexthrowsNullPointerExceptioninstead of refusing whenStatus.newSegmentsis null. That is the piece @gokaai explicitly deferred:The two are independent and can land in either order.
Verification
testCorruptSegmentInfoNamesTheSegmentfails without the fix, and fails again if the root cause is replaced with a synthetic one — so it checks the cause rather than just its presence:lucene:core:testforTestCheckIndex,TestTransactions,SegmentInfos*andIndexWriter*passes (362 tests):lucene:core:checkandtidypassVerified on
mainonly.