diff --git a/lucene/core/src/java/org/apache/lucene/index/TieredMergePolicy.java b/lucene/core/src/java/org/apache/lucene/index/TieredMergePolicy.java index d974148b4e4..0a98760b7ef 100644 --- a/lucene/core/src/java/org/apache/lucene/index/TieredMergePolicy.java +++ b/lucene/core/src/java/org/apache/lucene/index/TieredMergePolicy.java @@ -536,11 +536,16 @@ public class TieredMergePolicy extends MergePolicy { SegmentSizeAndDocs maxCandidateSegmentSize = segInfosSizes.get(candidate.get(0)); if (hitTooLarge == false && mergeType == MERGE_TYPE.NATURAL - && bytesThisMerge < maxCandidateSegmentSize.sizeInBytes * 1.5) { + && bytesThisMerge < maxCandidateSegmentSize.sizeInBytes * 1.5 + && maxCandidateSegmentSize.delCount + < maxCandidateSegmentSize.maxDoc * deletesPctAllowed / 100) { // Ignore any merge where the resulting segment is not at least 50% larger than the // biggest input segment. // Otherwise we could run into pathological O(N^2) merging where merges keep rewriting // again and again the biggest input segment into a segment that is barely bigger. + // The only exception we make is when the merge would reclaim lots of deletes in the + // biggest segment. This is important for cases when lots of documents get deleted at once + // without introducing new segments of a similar size for instance. continue; }