Skip to content

Commit

Permalink
LUCENE-9722: Close merged readers on abort (#2288)
Browse files Browse the repository at this point in the history
We fail to close the merged readers of an aborted merge if its 
output segment contains no document.

This bug was discovered by a test in Elasticsearch 
(elastic/elasticsearch#67884).
  • Loading branch information
dnhatn authored Feb 2, 2021
1 parent 4cb1000 commit 47e3d06
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5019,8 +5019,7 @@ public int length() {
// Merge would produce a 0-doc segment, so we do nothing except commit the merge to remove
// all the 0-doc segments that we "merged":
assert merge.info.info.maxDoc() == 0;
commitMerge(merge, mergeState);
success = true;
success = commitMerge(merge, mergeState);
return 0;
}

Expand Down
35 changes: 35 additions & 0 deletions lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3847,6 +3847,41 @@ public void testSoftAndHardLiveDocs() throws IOException {
IOUtils.close(writer, dir);
}

public void testAbortFullyDeletedSegment() throws Exception {
AtomicBoolean abortMergeBeforeCommit = new AtomicBoolean();
OneMergeWrappingMergePolicy mergePolicy =
new OneMergeWrappingMergePolicy(
newMergePolicy(),
toWrap ->
new MergePolicy.OneMerge(toWrap.segments) {
@Override
void onMergeComplete() throws IOException {
super.onMergeComplete();
if (abortMergeBeforeCommit.get()) {
setAborted();
}
}
}) {
@Override
public boolean keepFullyDeletedSegment(IOSupplier<CodecReader> readerIOSupplier) {
return true;
}
};

Directory dir = newDirectory();
IndexWriterConfig indexWriterConfig =
newIndexWriterConfig().setMergePolicy(mergePolicy).setCommitOnClose(false);
IndexWriter writer = new IndexWriter(dir, indexWriterConfig);
writer.addDocument(Collections.singletonList(new StringField("id", "1", Field.Store.YES)));
writer.flush();

writer.deleteDocuments(new Term("id", "1"));
abortMergeBeforeCommit.set(true);
writer.flush();
writer.forceMerge(1);
IOUtils.close(writer, dir);
}

private void assertHardLiveDocs(IndexWriter writer, Set<Integer> uniqueDocs) throws IOException {
try (DirectoryReader reader = DirectoryReader.open(writer)) {
assertEquals(uniqueDocs.size(), reader.numDocs());
Expand Down

0 comments on commit 47e3d06

Please sign in to comment.