LUCENE-9722: Close merged readers on abort (#2288)

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).
This commit is contained in:
Nhat Nguyen 2021-02-02 11:24:10 -05:00 committed by GitHub
parent 4cb1000ea0
commit 47e3d06ce0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 2 deletions

View File

@ -5019,8 +5019,7 @@ public class IndexWriter
// 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;
}

View File

@ -3847,6 +3847,41 @@ public class TestIndexWriter extends LuceneTestCase {
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());