recovery: don't replay log file on clean shutdown + startup

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1239465 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2012-02-02 05:59:55 +00:00
parent 0456daf3bb
commit 26cc705354
3 changed files with 70 additions and 6 deletions

View File

@ -533,7 +533,7 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
// we shouldn't close the transaction logs either, but leaving them open
// means we can't delete them on windows.
if (ulog != null) ulog.close();
if (ulog != null) ulog.close(false);
return;
}
@ -543,11 +543,9 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
}
// if the writer hits an exception, it's OK (and perhaps desirable)
// to not close the ulog?
// to not close the ulog.
// Closing the log currently deletes the log file.
// If this changes, we should record this as a "commit".
if (ulog != null) ulog.close();
if (ulog != null) ulog.close(true);
} finally {
commitLock.unlock();
}

View File

@ -20,7 +20,9 @@ package org.apache.solr.update;
import org.apache.lucene.util.BytesRef;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrCore;
@ -580,7 +582,7 @@ public class UpdateLog implements PluginInfoInitialized {
}
}
public void close() {
public void close(boolean committed) {
synchronized (this) {
try {
recoveryExecutor.shutdownNow();
@ -596,6 +598,12 @@ public class UpdateLog implements PluginInfoInitialized {
prevTlog.forceClose();
}
if (tlog != null) {
if (committed) {
// record a commit
CommitUpdateCommand cmd = new CommitUpdateCommand(new LocalSolrQueryRequest(uhandler.core, new ModifiableSolrParams((SolrParams)null)), false);
tlog.writeCommit(cmd);
}
tlog.deleteOnClose = false;
tlog.decref();
tlog.forceClose();

View File

@ -448,6 +448,64 @@ public class TestRecovery extends SolrTestCaseJ4 {
);
}
// make sure that log isn't needlessly replayed after a clean shutdown
@Test
public void testCleanShutdown() throws Exception {
DirectUpdateHandler2.commitOnClose = true;
final Semaphore logReplay = new Semaphore(0);
final Semaphore logReplayFinish = new Semaphore(0);
UpdateLog.testing_logReplayHook = new Runnable() {
@Override
public void run() {
try {
assertTrue(logReplay.tryAcquire(timeout, TimeUnit.SECONDS));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
UpdateLog.testing_logReplayFinishHook = new Runnable() {
@Override
public void run() {
logReplayFinish.release();
}
};
SolrQueryRequest req = req();
UpdateHandler uhandler = req.getCore().getUpdateHandler();
UpdateLog ulog = uhandler.getUpdateLog();
try {
clearIndex();
assertU(commit());
assertU(adoc("id","1", "val_i","1"));
assertU(adoc("id","2", "val_i","1"));
// set to a high enough number so this test won't hang on a bug
logReplay.release(10);
h.close();
createCore();
// make sure the docs got committed
assertJQ(req("q","*:*"),"/response/numFound==2");
// make sure no replay happened
assertEquals(10, logReplay.availablePermits());
} finally {
DirectUpdateHandler2.commitOnClose = true;
UpdateLog.testing_logReplayHook = null;
UpdateLog.testing_logReplayFinishHook = null;
req().close();
}
}
private void addDocs(int nDocs, int start, LinkedList<Long> versions) throws Exception {