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

View File

@ -20,7 +20,9 @@ package org.apache.solr.update;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument; 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.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.PluginInfo; import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrCore; 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) { synchronized (this) {
try { try {
recoveryExecutor.shutdownNow(); recoveryExecutor.shutdownNow();
@ -596,6 +598,12 @@ public class UpdateLog implements PluginInfoInitialized {
prevTlog.forceClose(); prevTlog.forceClose();
} }
if (tlog != null) { 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.deleteOnClose = false;
tlog.decref(); tlog.decref();
tlog.forceClose(); 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 { private void addDocs(int nDocs, int start, LinkedList<Long> versions) throws Exception {