LUCENE-948: handle stale dir listing caches on NFS (so quickly switching writers between machines works)

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@562546 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2007-08-03 18:41:22 +00:00
parent 19ca21a1dd
commit 32b981044f
3 changed files with 35 additions and 6 deletions

View File

@ -61,6 +61,11 @@ Bug fixes
9. LUCENE-832: ParallelReader fixed to not throw NPE if isCurrent(), 9. LUCENE-832: ParallelReader fixed to not throw NPE if isCurrent(),
isOptimized() or getVersion() is called. (Michael Busch) isOptimized() or getVersion() is called. (Michael Busch)
10. LUCENE-948: Fix FNFE exception caused by stale NFS client
directory listing caches when writers on different machines are
sharing an index over NFS and using a custom deletion policy (Mike
McCandless)
New features New features
1. LUCENE-906: Elision filter for French. 1. LUCENE-906: Elision filter for French.

View File

@ -23,6 +23,7 @@ import org.apache.lucene.index.SegmentInfo;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import java.io.IOException; import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
@ -123,6 +124,9 @@ final class IndexFileDeleter {
this.docWriter = docWriter; this.docWriter = docWriter;
this.infoStream = infoStream; this.infoStream = infoStream;
if (infoStream != null)
message("init: current segments file is \"" + segmentInfos.getCurrentSegmentFileName() + "\"");
this.policy = policy; this.policy = policy;
this.directory = directory; this.directory = directory;
@ -156,7 +160,22 @@ final class IndexFileDeleter {
message("init: load commit \"" + fileName + "\""); message("init: load commit \"" + fileName + "\"");
} }
SegmentInfos sis = new SegmentInfos(); SegmentInfos sis = new SegmentInfos();
try {
sis.read(directory, fileName); sis.read(directory, fileName);
} catch (FileNotFoundException e) {
// LUCENE-948: on NFS (and maybe others), if
// you have writers switching back and forth
// between machines, it's very likely that the
// dir listing will be stale and will claim a
// file segments_X exists when in fact it
// doesn't. So, we catch this and handle it
// as if the file does not exist
if (infoStream != null) {
message("init: hit FileNotFoundException when loading commit \"" + fileName + "\"; skipping this commit point");
}
sis = null;
}
if (sis != null) {
CommitPoint commitPoint = new CommitPoint(sis); CommitPoint commitPoint = new CommitPoint(sis);
if (sis.getGeneration() == segmentInfos.getGeneration()) { if (sis.getGeneration() == segmentInfos.getGeneration()) {
currentCommitPoint = commitPoint; currentCommitPoint = commitPoint;
@ -167,6 +186,7 @@ final class IndexFileDeleter {
} }
} }
} }
}
if (currentCommitPoint == null) { if (currentCommitPoint == null) {
throw new CorruptIndexException("failed to locate current segments_N file"); throw new CorruptIndexException("failed to locate current segments_N file");

View File

@ -928,6 +928,8 @@ public class IndexWriter {
if (commitPending) { if (commitPending) {
segmentInfos.write(directory); // now commit changes segmentInfos.write(directory); // now commit changes
if (infoStream != null)
infoStream.println("close: wrote segments file \"" + segmentInfos.getCurrentSegmentFileName() + "\"");
deleter.checkpoint(segmentInfos, true); deleter.checkpoint(segmentInfos, true);
commitPending = false; commitPending = false;
rollbackSegmentInfos = null; rollbackSegmentInfos = null;
@ -1478,6 +1480,8 @@ public class IndexWriter {
private void checkpoint() throws IOException { private void checkpoint() throws IOException {
if (autoCommit) { if (autoCommit) {
segmentInfos.write(directory); segmentInfos.write(directory);
if (infoStream != null)
infoStream.println("checkpoint: wrote segments file \"" + segmentInfos.getCurrentSegmentFileName() + "\"");
} else { } else {
commitPending = true; commitPending = true;
} }