mirror of https://github.com/apache/lucene.git
LUCENE-962: fixed case where unhandled exception in addDocument or updateDocument could fail to delete unreferenced files in the index
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@557082 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
52b5113a04
commit
aae68e0ba6
|
@ -35,6 +35,11 @@ Bug fixes
|
||||||
IndexWriter's methods could cause deletes to be lost.
|
IndexWriter's methods could cause deletes to be lost.
|
||||||
(Steven Parkes via Mike McCandless)
|
(Steven Parkes via Mike McCandless)
|
||||||
|
|
||||||
|
4. LUCENE-962: Fixed case where an unhandled exception in
|
||||||
|
IndexWriter.addDocument or IndexWriter.updateDocument could cause
|
||||||
|
unreferenced files in the index to not be deleted
|
||||||
|
(Steven Parkes via Mike McCandless)
|
||||||
|
|
||||||
New features
|
New features
|
||||||
|
|
||||||
1. LUCENE-906: Elision filter for French.
|
1. LUCENE-906: Elision filter for French.
|
||||||
|
|
|
@ -1112,7 +1112,14 @@ public class IndexWriter {
|
||||||
*/
|
*/
|
||||||
public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException {
|
public void addDocument(Document doc, Analyzer analyzer) throws CorruptIndexException, IOException {
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
if (docWriter.addDocument(doc, analyzer))
|
boolean success = false;
|
||||||
|
try {
|
||||||
|
success = docWriter.addDocument(doc, analyzer);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
deleter.refresh();
|
||||||
|
throw ioe;
|
||||||
|
}
|
||||||
|
if (success)
|
||||||
flush(true, false);
|
flush(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1180,7 +1187,14 @@ public class IndexWriter {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
bufferDeleteTerm(term);
|
bufferDeleteTerm(term);
|
||||||
}
|
}
|
||||||
if (docWriter.addDocument(doc, analyzer))
|
boolean success = false;
|
||||||
|
try {
|
||||||
|
success = docWriter.addDocument(doc, analyzer);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
deleter.refresh();
|
||||||
|
throw ioe;
|
||||||
|
}
|
||||||
|
if (success)
|
||||||
flush(true, false);
|
flush(true, false);
|
||||||
else
|
else
|
||||||
maybeFlush();
|
maybeFlush();
|
||||||
|
|
|
@ -576,8 +576,7 @@ public class TestIndexWriterDelete extends TestCase {
|
||||||
|
|
||||||
for(int pass=0;pass<2;pass++) {
|
for(int pass=0;pass<2;pass++) {
|
||||||
boolean autoCommit = (0==pass);
|
boolean autoCommit = (0==pass);
|
||||||
Directory ramDir = new RAMDirectory();
|
MockRAMDirectory dir = new MockRAMDirectory();
|
||||||
MockRAMDirectory dir = new MockRAMDirectory(ramDir);
|
|
||||||
IndexWriter modifier = new IndexWriter(dir, autoCommit,
|
IndexWriter modifier = new IndexWriter(dir, autoCommit,
|
||||||
new WhitespaceAnalyzer(), true);
|
new WhitespaceAnalyzer(), true);
|
||||||
modifier.setUseCompoundFile(true);
|
modifier.setUseCompoundFile(true);
|
||||||
|
@ -675,6 +674,75 @@ public class TestIndexWriterDelete extends TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test tests that the files created by the docs writer before
|
||||||
|
// a segment is written are cleaned up if there's an i/o error
|
||||||
|
|
||||||
|
public void testErrorInDocsWriterAdd() throws IOException {
|
||||||
|
|
||||||
|
MockRAMDirectory.Failure failure = new MockRAMDirectory.Failure() {
|
||||||
|
boolean failed = false;
|
||||||
|
public MockRAMDirectory.Failure reset() {
|
||||||
|
failed = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public void eval(MockRAMDirectory dir) throws IOException {
|
||||||
|
if (!failed) {
|
||||||
|
throw new IOException("fail in add doc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// create a couple of files
|
||||||
|
|
||||||
|
String[] keywords = { "1", "2" };
|
||||||
|
String[] unindexed = { "Netherlands", "Italy" };
|
||||||
|
String[] unstored = { "Amsterdam has lots of bridges",
|
||||||
|
"Venice has lots of canals" };
|
||||||
|
String[] text = { "Amsterdam", "Venice" };
|
||||||
|
|
||||||
|
for(int pass=0;pass<2;pass++) {
|
||||||
|
boolean autoCommit = (0==pass);
|
||||||
|
MockRAMDirectory dir = new MockRAMDirectory();
|
||||||
|
IndexWriter modifier = new IndexWriter(dir, autoCommit,
|
||||||
|
new WhitespaceAnalyzer(), true);
|
||||||
|
|
||||||
|
dir.failOn(failure.reset());
|
||||||
|
|
||||||
|
for (int i = 0; i < keywords.length; i++) {
|
||||||
|
Document doc = new Document();
|
||||||
|
doc.add(new Field("id", keywords[i], Field.Store.YES,
|
||||||
|
Field.Index.UN_TOKENIZED));
|
||||||
|
doc.add(new Field("country", unindexed[i], Field.Store.YES,
|
||||||
|
Field.Index.NO));
|
||||||
|
doc.add(new Field("contents", unstored[i], Field.Store.NO,
|
||||||
|
Field.Index.TOKENIZED));
|
||||||
|
doc.add(new Field("city", text[i], Field.Store.YES,
|
||||||
|
Field.Index.TOKENIZED));
|
||||||
|
try {
|
||||||
|
modifier.addDocument(doc);
|
||||||
|
} catch (IOException io) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] startFiles = dir.list();
|
||||||
|
SegmentInfos infos = new SegmentInfos();
|
||||||
|
infos.read(dir);
|
||||||
|
IndexFileDeleter d = new IndexFileDeleter(dir, new KeepOnlyLastCommitDeletionPolicy(), infos, null, null);
|
||||||
|
String[] endFiles = dir.list();
|
||||||
|
|
||||||
|
if (!Arrays.equals(startFiles, endFiles)) {
|
||||||
|
fail("docswriter abort() failed to delete unreferenced files:\n before delete:\n "
|
||||||
|
+ arrayToString(startFiles) + "\n after delete:\n "
|
||||||
|
+ arrayToString(endFiles));
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private String arrayToString(String[] l) {
|
private String arrayToString(String[] l) {
|
||||||
String s = "";
|
String s = "";
|
||||||
for (int i = 0; i < l.length; i++) {
|
for (int i = 0; i < l.length; i++) {
|
||||||
|
|
Loading…
Reference in New Issue