From 32b981044f8c35ba2d1ece13cb0ec3aa941aef48 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Fri, 3 Aug 2007 18:41:22 +0000 Subject: [PATCH] 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 --- CHANGES.txt | 5 +++ .../apache/lucene/index/IndexFileDeleter.java | 32 +++++++++++++++---- .../org/apache/lucene/index/IndexWriter.java | 4 +++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d8e4ab77fe6..2c24dfdfb78 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -61,6 +61,11 @@ Bug fixes 9. LUCENE-832: ParallelReader fixed to not throw NPE if isCurrent(), 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 1. LUCENE-906: Elision filter for French. diff --git a/src/java/org/apache/lucene/index/IndexFileDeleter.java b/src/java/org/apache/lucene/index/IndexFileDeleter.java index 2675517dc05..fd39c8d98c3 100644 --- a/src/java/org/apache/lucene/index/IndexFileDeleter.java +++ b/src/java/org/apache/lucene/index/IndexFileDeleter.java @@ -23,6 +23,7 @@ import org.apache.lucene.index.SegmentInfo; import org.apache.lucene.store.Directory; import java.io.IOException; +import java.io.FileNotFoundException; import java.io.PrintStream; import java.util.Map; import java.util.HashMap; @@ -123,6 +124,9 @@ final class IndexFileDeleter { this.docWriter = docWriter; this.infoStream = infoStream; + if (infoStream != null) + message("init: current segments file is \"" + segmentInfos.getCurrentSegmentFileName() + "\""); + this.policy = policy; this.directory = directory; @@ -156,13 +160,29 @@ final class IndexFileDeleter { message("init: load commit \"" + fileName + "\""); } SegmentInfos sis = new SegmentInfos(); - sis.read(directory, fileName); - CommitPoint commitPoint = new CommitPoint(sis); - if (sis.getGeneration() == segmentInfos.getGeneration()) { - currentCommitPoint = commitPoint; + try { + 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); + if (sis.getGeneration() == segmentInfos.getGeneration()) { + currentCommitPoint = commitPoint; + } + commits.add(commitPoint); + incRef(sis, true); } - commits.add(commitPoint); - incRef(sis, true); } } } diff --git a/src/java/org/apache/lucene/index/IndexWriter.java b/src/java/org/apache/lucene/index/IndexWriter.java index 02826ada590..7cb68faf7e3 100644 --- a/src/java/org/apache/lucene/index/IndexWriter.java +++ b/src/java/org/apache/lucene/index/IndexWriter.java @@ -928,6 +928,8 @@ public class IndexWriter { if (commitPending) { segmentInfos.write(directory); // now commit changes + if (infoStream != null) + infoStream.println("close: wrote segments file \"" + segmentInfos.getCurrentSegmentFileName() + "\""); deleter.checkpoint(segmentInfos, true); commitPending = false; rollbackSegmentInfos = null; @@ -1478,6 +1480,8 @@ public class IndexWriter { private void checkpoint() throws IOException { if (autoCommit) { segmentInfos.write(directory); + if (infoStream != null) + infoStream.println("checkpoint: wrote segments file \"" + segmentInfos.getCurrentSegmentFileName() + "\""); } else { commitPending = true; }