Index: src/test/org/apache/lucene/index/TestIndexWriter.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexWriter.java (revision 681089) +++ src/test/org/apache/lucene/index/TestIndexWriter.java (working copy) @@ -2804,8 +2804,8 @@ super(dir, new StandardAnalyzer()); myDir = dir; } - synchronized MergePolicy.OneMerge getNextMerge() { - MergePolicy.OneMerge merge = super.getNextMerge(); + synchronized MergePolicy.OneMerge getNextMerge(boolean allowExternal) { + MergePolicy.OneMerge merge = super.getNextMerge(allowExternal); if (merge != null) mergeCount++; return merge; Index: src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java =================================================================== --- src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (revision 674334) +++ src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (working copy) @@ -241,7 +241,7 @@ // Subsequent times through the loop we do any new // merge that writer says is necessary: - merge = writer.getNextMerge(); + merge = writer.getNextMerge(false); if (merge != null) { writer.mergeInit(merge); message(" merge thread: do another merge " + merge.segString(dir)); Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 681089) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -1778,6 +1778,12 @@ } catch (InterruptedException ie) { } + // Sicne we may have external segments in the + // index, which CMS BG threads can't touch, we + // need to give FG thread a chance to run merges + // here: + maybeMerge(maxNumSegments, true); + if (mergeExceptions.size() > 0) { // Forward any exceptions in background merge // threads to the current thread: @@ -1871,18 +1877,31 @@ /** Expert: the {@link MergeScheduler} calls this method * to retrieve the next merge requested by the - * MergePolicy */ - synchronized MergePolicy.OneMerge getNextMerge() { + * MergePolicy. If allowExternal is true then any + * pending merge may be returned; else, only merges not + * involving external segments may be returned. */ + synchronized MergePolicy.OneMerge getNextMerge(boolean allowExternal) { if (pendingMerges.size() == 0) return null; else { - // Advance the merge from pending to running - MergePolicy.OneMerge merge = (MergePolicy.OneMerge) pendingMerges.removeFirst(); - runningMerges.add(merge); - return merge; + Iterator it = pendingMerges.iterator(); + while(it.hasNext()) { + MergePolicy.OneMerge merge = (MergePolicy.OneMerge) it.next(); + if (allowExternal || !merge.isExternal) { + // Advance the merge from pending to running + it.remove(); + runningMerges.add(merge); + return merge; + } + } + return null; } } + synchronized MergePolicy.OneMerge getNextMerge() { + return getNextMerge(true); + } + /* * Begin a transaction. During a transaction, any segment * merges that happen (or ram segments flushed) will not