From 47e3d06ce00642624634e5d45ebc16fa33d48099 Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Tue, 2 Feb 2021 11:24:10 -0500 Subject: [PATCH] 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). --- .../org/apache/lucene/index/IndexWriter.java | 3 +- .../apache/lucene/index/TestIndexWriter.java | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java index 3e5da9fa67e..8b7e9e052e6 100644 --- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java +++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java @@ -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; } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java index c0065ca3eed..1a5e87a40ce 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java @@ -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 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 uniqueDocs) throws IOException { try (DirectoryReader reader = DirectoryReader.open(writer)) { assertEquals(uniqueDocs.size(), reader.numDocs());