Author: mreutegg
Date: Tue Jul 25 14:19:59 2017
New Revision: 1802948
URL: http://svn.apache.org/viewvc?rev=1802948&view=rev
Log:
OAK-5602: Avoid missing journal entries
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalGCTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1802948&r1=1802947&r2=1802948&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
Tue Jul 25 14:19:59 2017
@@ -24,7 +24,9 @@ import static com.google.common.collect.
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.reverse;
import static java.util.Collections.singletonList;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.jackrabbit.oak.api.CommitFailedException.OAK;
import static org.apache.jackrabbit.oak.commons.PathUtils.ROOT_PATH;
import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
import static
org.apache.jackrabbit.oak.plugins.document.Collection.CLUSTER_NODES;
@@ -1694,6 +1696,10 @@ public final class DocumentNodeStore
UpdateOp op = new UpdateOp(Utils.getIdFromPath("/"), false);
NodeDocument.setModified(op, commit.getRevision());
if (b != null) {
+ // check the branch age and fail the commit
+ // if the first branch commit is too old
+ checkBranchAge(b);
+
commit.addBranchCommits(b);
Iterator<Revision> mergeCommits =
commit.getMergeRevisions().iterator();
for (Revision rev : b.getCommits()) {
@@ -2718,11 +2724,14 @@ public final class DocumentNodeStore
long minTimestamp = Utils.getMinTimestampForDiff(
from.getRootRevision(), to.getRootRevision(),
getMinExternalRevisions());
+ long minJournalTimestamp = newRevision().getTimestamp() -
+ journalGarbageCollector.getMaxRevisionAgeMillis() / 2;
// use journal if possible
Revision tailRev = journalGarbageCollector.getTailRevision();
if (!disableJournalDiff
- && tailRev.getTimestamp() < minTimestamp) {
+ && tailRev.getTimestamp() < minTimestamp
+ && minJournalTimestamp < minTimestamp) {
diffAlgo = "diffJournalChildren";
fromRev = from.getRootRevision();
toRev = to.getRootRevision();
@@ -2912,6 +2921,22 @@ public final class DocumentNodeStore
return System.currentTimeMillis();
}
+ private void checkBranchAge(Branch b) throws CommitFailedException {
+ // check if initial branch commit is too old to merge
+ long journalMaxAge = journalGarbageCollector.getMaxRevisionAgeMillis();
+ long branchMaxAge = journalMaxAge / 2;
+ long created = b.getCommits().first().getTimestamp();
+ long branchAge = newRevision().getTimestamp() - created;
+ if (branchAge > branchMaxAge) {
+ String msg = "Long running commit detected. Branch was created " +
+ Utils.timestampToString(created) + ". Consider breaking " +
+ "the commit down into smaller pieces or increasing the " +
+ "'journalGCMaxAge' currently set to " + journalMaxAge +
+ " ms (" + MILLISECONDS.toMinutes(journalMaxAge) + " min).";
+ throw new CommitFailedException(OAK, 200, msg);
+ }
+ }
+
/**
* Creates and returns a MarkSweepGarbageCollector if the current BlobStore
* supports garbage collection
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java?rev=1802948&r1=1802947&r2=1802948&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
Tue Jul 25 14:19:59 2017
@@ -77,11 +77,17 @@ public class JournalGarbageCollector {
*/
public int gc() {
DocumentStore ds = ns.getDocumentStore();
- Revision keep = ns.getCheckpoints().getOldestRevisionToKeep();
+ Revision checkpointRev = ns.getCheckpoints().getOldestRevisionToKeep();
+ Long keep = null;
+ if (checkpointRev != null) {
+ // keep more entries than just up to the checkpoint to account
+ // for branch commits that may be referenced by merge commits
+ keep = checkpointRev.getTimestamp() - maxRevisionAgeMillis / 2;
+ }
long now = ns.getClock().getTime();
long gcOlderThan = now - maxRevisionAgeMillis;
- if (keep != null && keep.getTimestamp() < gcOlderThan) {
- gcOlderThan = keep.getTimestamp();
+ if (keep != null && keep < gcOlderThan) {
+ gcOlderThan = keep;
log.debug("gc: Checkpoint {} is older than maxRevisionAge: {} min",
keep, MILLISECONDS.toMinutes(maxRevisionAgeMillis));
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1802948&r1=1802947&r2=1802948&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
Tue Jul 25 14:19:59 2017
@@ -3320,7 +3320,6 @@ public class DocumentNodeStoreTest {
}
// OAK-5602
- @Ignore("OAK-5602")
@Test
public void longRunningTx() throws Exception {
Clock clock = new Clock.Virtual();
@@ -3375,7 +3374,6 @@ public class DocumentNodeStoreTest {
after.compareAgainstBaseState(before, new DefaultNodeStateDiff());
}
- @Ignore("OAK-5602")
@Test
public void failLongRunningTx() throws Exception {
Clock clock = new Clock.Virtual();
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalGCTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalGCTest.java?rev=1802948&r1=1802947&r2=1802948&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalGCTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalGCTest.java
Tue Jul 25 14:19:59 2017
@@ -32,7 +32,6 @@ import org.apache.jackrabbit.oak.stats.C
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
@@ -116,7 +115,6 @@ public class JournalGCTest {
}
// OAK-5602
- @Ignore("OAK-5602")
@Test
public void gcWithCheckpoint2() throws Exception {
Clock c = new Clock.Virtual();