LUCENE-3182: fix corruption case, when one thread is calling IW.addIndices(IR...) and another thread calls IW.rollback()

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1133565 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2011-06-08 21:39:02 +00:00
parent 506f927191
commit 83a79b6f67
3 changed files with 24 additions and 2 deletions

View File

@ -22,7 +22,6 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;

View File

@ -1999,6 +1999,9 @@ public class IndexWriter implements Closeable {
// will always write to a new generation ("write
// once").
segmentInfos.rollbackSegmentInfos(rollbackSegments);
if (infoStream != null ) {
message("rollback: infos=" + segString(segmentInfos));
}
docWriter.abort();
@ -2439,6 +2442,8 @@ public class IndexWriter implements Closeable {
flush(false, true);
String mergedName = newSegmentName();
// TODO: somehow we should fix this merge so it's
// abortable so that IW.close(false) is able to stop it
SegmentMerger merger = new SegmentMerger(directory, config.getTermIndexInterval(),
mergedName, null, payloadProcessorProvider,
globalFieldNumberMap.newFieldInfos(SegmentCodecsBuilder.create(codecs)));
@ -2456,6 +2461,11 @@ public class IndexWriter implements Closeable {
boolean useCompoundFile;
synchronized(this) { // Guard segmentInfos
if (stopMerges) {
deleter.deleteNewFiles(info.files());
return;
}
ensureOpen();
useCompoundFile = mergePolicy.useCompoundFile(segmentInfos, info);
}
@ -2471,6 +2481,11 @@ public class IndexWriter implements Closeable {
// Register the new segment
synchronized(this) {
if (stopMerges) {
deleter.deleteNewFiles(info.files());
return;
}
ensureOpen();
segmentInfos.add(info);
checkpoint();
}
@ -3076,6 +3091,7 @@ public class IndexWriter implements Closeable {
boolean success = false;
final long t0 = System.currentTimeMillis();
//System.out.println(Thread.currentThread().getName() + ": merge start: size=" + (merge.estimatedMergeBytes/1024./1024.) + " MB\n merge=" + merge.segString(directory) + "\n idx=" + segString());
try {
try {
@ -3116,6 +3132,7 @@ public class IndexWriter implements Closeable {
if (infoStream != null && merge.info != null) {
message("merge time " + (System.currentTimeMillis()-t0) + " msec for " + merge.info.docCount + " docs");
}
//System.out.println(Thread.currentThread().getName() + ": merge end");
}
/** Hook that's called when the specified merge is complete. */
@ -3734,6 +3751,8 @@ public class IndexWriter implements Closeable {
assert testPoint("midStartCommit");
boolean pendingCommitSet = false;
try {
// This call can take a long time -- 10s of seconds
// or more. We do it without sync:
@ -3753,6 +3772,7 @@ public class IndexWriter implements Closeable {
toSync.prepareCommit(directory);
pendingCommit = toSync;
pendingCommitSet = true;
pendingCommitChangeCount = myChangeCount;
}
@ -3770,7 +3790,7 @@ public class IndexWriter implements Closeable {
// double-write a segments_N file.
segmentInfos.updateGeneration(toSync);
if (pendingCommit == null) {
if (!pendingCommitSet) {
if (infoStream != null) {
message("hit exception committing segments file");
}

View File

@ -18,6 +18,7 @@ package org.apache.lucene.index;
*/
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
@ -866,6 +867,8 @@ public class TestAddIndexes extends LuceneTestCase {
if (t instanceof AlreadyClosedException || t instanceof MergePolicy.MergeAbortedException || t instanceof NullPointerException) {
report = !didClose;
} else if (t instanceof FileNotFoundException) {
report = !didClose;
} else if (t instanceof IOException) {
Throwable t2 = t.getCause();
if (t2 instanceof MergePolicy.MergeAbortedException) {