You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by dp...@apache.org on 2012/08/22 16:53:18 UTC
svn commit: r1376084 - in /jackrabbit/oak/trunk/oak-mk: ./
src/main/java/org/apache/jackrabbit/mk/model/
src/main/java/org/apache/jackrabbit/mk/persistence/
src/main/java/org/apache/jackrabbit/mk/store/
Author: dpfister
Date: Wed Aug 22 14:53:18 2012
New Revision: 1376084
URL: http://svn.apache.org/viewvc?rev=1376084&view=rev
Log:
OAK-216 - Occasional org.apache.jackrabbit.mk.store.NotFoundExceptions
- add logging support to oak-mk
Modified:
jackrabbit/oak/trunk/oak-mk/pom.xml
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/RevisionStore.java
Modified: jackrabbit/oak/trunk/oak-mk/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/pom.xml?rev=1376084&r1=1376083&r2=1376084&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-mk/pom.xml Wed Aug 22 14:53:18 2012
@@ -93,6 +93,13 @@
<version>${project.version}</version>
</dependency>
+ <!-- Logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.6.4</version>
+ </dependency>
+
<!-- default persistence backend -->
<dependency>
<groupId>com.h2database</groupId>
@@ -121,6 +128,12 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.0.1</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java?rev=1376084&r1=1376083&r2=1376084&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/CommitBuilder.java Wed Aug 22 14:53:18 2012
@@ -156,7 +156,7 @@ public class CommitBuilder {
newCommit.setChanges(diff.toString());
newCommit.setRootNodeId(rootNodeId);
newCommit.setBranchRootId(null);
- newRevId = store.putHeadCommit(token, newCommit, null);
+ newRevId = store.putHeadCommit(token, newCommit, null, null);
} finally {
store.unlockHead();
}
@@ -228,7 +228,7 @@ public class CommitBuilder {
newCommit.setChanges(diff);
newCommit.setRootNodeId(rootNodeId);
newCommit.setBranchRootId(null);
- newRevId = store.putHeadCommit(token, newCommit, branchRootId);
+ newRevId = store.putHeadCommit(token, newCommit, branchRootId, baseRevId);
} finally {
store.unlockHead();
}
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java?rev=1376084&r1=1376083&r2=1376084&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java Wed Aug 22 14:53:18 2012
@@ -86,7 +86,8 @@ public interface GCPersistence extends P
/**
* Sweep all objects that are not marked and were written before the GC started.
*
+ * @return number of swept items or <code>-1</code> if number is unknown
* @throws Exception if an error occurs
*/
- void sweep() throws Exception;
+ int sweep() throws Exception;
}
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java?rev=1376084&r1=1376083&r2=1376084&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java Wed Aug 22 14:53:18 2012
@@ -141,17 +141,19 @@ public class H2Persistence implements GC
node.serialize(new BinaryBinding(out));
byte[] bytes = out.toByteArray();
byte[] rawId = idFactory.createContentId(bytes);
+ Timestamp ts = new Timestamp(System.currentTimeMillis());
//String id = StringUtils.convertBytesToHex(rawId);
Connection con = cp.getConnection();
try {
PreparedStatement stmt = con
.prepareStatement(
- "insert into REVS (ID, DATA, TIME) select ?, ?, CURRENT_TIMESTAMP() where not exists (select 1 from REVS where ID = ?)");
+ "insert into REVS (ID, DATA, TIME) select ?, ?, ? where not exists (select 1 from REVS where ID = ?)");
try {
stmt.setBytes(1, rawId);
stmt.setBytes(2, bytes);
- stmt.setBytes(3, rawId);
+ stmt.setTimestamp(3, ts);
+ stmt.setBytes(4, rawId);
stmt.executeUpdate();
} finally {
stmt.close();
@@ -187,16 +189,18 @@ public class H2Persistence implements GC
ByteArrayOutputStream out = new ByteArrayOutputStream();
commit.serialize(new BinaryBinding(out));
byte[] bytes = out.toByteArray();
+ Timestamp ts = new Timestamp(System.currentTimeMillis());
Connection con = cp.getConnection();
try {
PreparedStatement stmt = con
.prepareStatement(
- "insert into REVS (ID, DATA, TIME) select ?, ?, CURRENT_TIMESTAMP() where not exists (select 1 from REVS where ID = ?)");
+ "insert into REVS (ID, DATA, TIME) select ?, ?, ? where not exists (select 1 from REVS where ID = ?)");
try {
stmt.setBytes(1, id.getBytes());
stmt.setBytes(2, bytes);
- stmt.setBytes(3, id.getBytes());
+ stmt.setTimestamp(3, ts);
+ stmt.setBytes(4, id.getBytes());
stmt.executeUpdate();
} finally {
stmt.close();
@@ -232,16 +236,18 @@ public class H2Persistence implements GC
map.serialize(new BinaryBinding(out));
byte[] bytes = out.toByteArray();
byte[] rawId = idFactory.createContentId(bytes);
+ Timestamp ts = new Timestamp(System.currentTimeMillis());
Connection con = cp.getConnection();
try {
PreparedStatement stmt = con
.prepareStatement(
- "insert into REVS (ID, DATA, TIME) select ?, ?, CURRENT_TIMESTAMP() where not exists (select 1 from REVS where ID = ?)");
+ "insert into REVS (ID, DATA, TIME) select ?, ?, ? where not exists (select 1 from REVS where ID = ?)");
try {
stmt.setBytes(1, rawId);
stmt.setBytes(2, bytes);
- stmt.setBytes(3, rawId);
+ stmt.setTimestamp(3, ts);
+ stmt.setBytes(4, rawId);
stmt.executeUpdate();
} finally {
stmt.close();
@@ -317,7 +323,7 @@ public class H2Persistence implements GC
}
@Override
- public void sweep() throws Exception {
+ public int sweep() throws Exception {
Timestamp ts = new Timestamp(gcStart);
Connection con = cp.getConnection();
@@ -327,7 +333,7 @@ public class H2Persistence implements GC
"delete REVS where TIME < ?");
try {
stmt.setTimestamp(1, ts);
- stmt.executeUpdate();
+ return stmt.executeUpdate();
} finally {
stmt.close();
}
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java?rev=1376084&r1=1376083&r2=1376084&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java Wed Aug 22 14:53:18 2012
@@ -175,10 +175,13 @@ public class InMemPersistence implements
}
@Override
- public void sweep() {
+ public int sweep() {
+ int count = objects.size();
+
objects.clear();
objects.putAll(marked);
gcStart = 0;
+ return count;
}
}
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java?rev=1376084&r1=1376083&r2=1376084&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java Wed Aug 22 14:53:18 2012
@@ -32,6 +32,8 @@ import org.apache.jackrabbit.mk.persiste
import org.apache.jackrabbit.mk.persistence.Persistence;
import org.apache.jackrabbit.mk.util.IOUtils;
import org.apache.jackrabbit.mk.util.SimpleLRUCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.util.Collections;
@@ -55,6 +57,8 @@ import java.util.concurrent.locks.Reentr
public class DefaultRevisionStore extends AbstractRevisionStore implements
Closeable {
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultRevisionStore.class);
+
public static final String CACHE_SIZE = "mk.cacheSize";
public static final int DEFAULT_CACHE_SIZE = 10000;
@@ -82,6 +86,8 @@ public class DefaultRevisionStore extend
* GC run state.
*/
private final AtomicInteger gcState = new AtomicInteger();
+
+ private int markedNodes, markedCommits;
/**
* GC executor.
@@ -99,7 +105,7 @@ public class DefaultRevisionStore extend
private final ReentrantReadWriteLock tokensLock = new ReentrantReadWriteLock();
/**
- * Active branches (Key: branch root id, Value: branch head).
+ * Active branches (Key: current branch head, Value: branch root id).
*/
private final TreeMap<Id,Id> branches = new TreeMap<Id, Id>();
@@ -160,7 +166,7 @@ public class DefaultRevisionStore extend
gc();
}
}
- }, 60, 1, TimeUnit.MINUTES); // FIXME, see OAK-216
+ }, 10, 1, TimeUnit.MINUTES);
}
initialized = true;
@@ -292,7 +298,7 @@ public class DefaultRevisionStore extend
headLock.writeLock().lock();
}
- public Id putHeadCommit(PutToken token, MutableCommit commit, Id branchRootId)
+ public Id putHeadCommit(PutToken token, MutableCommit commit, Id branchRootId, Id branchRevId)
throws Exception {
verifyInitialized();
if (!headLock.writeLock().isHeldByCurrentThread()) {
@@ -304,9 +310,9 @@ public class DefaultRevisionStore extend
setHeadCommitId(id);
putTokens.remove(token);
- if (branchRootId != null) {
+ if (branchRevId != null) {
synchronized (branches) {
- branches.remove(branchRootId);
+ branches.remove(branchRevId);
}
}
return id;
@@ -321,10 +327,14 @@ public class DefaultRevisionStore extend
Id branchRootId = commit.getBranchRootId();
if (branchRootId != null) {
synchronized (branches) {
- branches.put(branchRootId, commitId);
+ Id parentId = commit.getParentId();
+ if (!parentId.equals(branchRootId)) {
+ /* not the first branch commit, replace its head */
+ branches.remove(parentId);
+ }
+ branches.put(commitId, branchRootId);
}
}
-
return commitId;
}
@@ -496,11 +506,20 @@ public class DefaultRevisionStore extend
// already running
return;
}
+
+ LOG.debug("GC started.");
+ markedCommits = markedNodes = 0;
try {
markUncommittedNodes();
Id firstBranchRootId = markBranches();
+ if (firstBranchRootId != null) {
+ LOG.debug("First branch root to be preserved: {}", firstBranchRootId);
+ }
Id firstCommitId = markCommits();
+ LOG.debug("First commit to be preserved: {}", firstCommitId);
+
+ LOG.debug("Marked {} commits, {} nodes.", markedCommits, markedNodes);
if (firstBranchRootId != null && firstBranchRootId.compareTo(firstCommitId) < 0) {
firstCommitId = firstBranchRootId;
@@ -515,21 +534,24 @@ public class DefaultRevisionStore extend
} catch (Exception e) {
/* unable to perform GC */
+ LOG.error("Exception occurred in GC cycle", e);
gcState.set(NOT_ACTIVE);
- e.printStackTrace();
return;
}
gcState.set(SWEEPING);
try {
- gcpm.sweep();
+ int swept = gcpm.sweep();
+ LOG.debug("GC cycle swept {} items", swept);
cache.clear();
} catch (Exception e) {
- e.printStackTrace();
+ LOG.error("Exception occurred in GC cycle", e);
} finally {
gcState.set(NOT_ACTIVE);
}
+
+ LOG.debug("GC stopped.");
}
/**
@@ -569,19 +591,23 @@ public class DefaultRevisionStore extend
tmpBranches = (Map<Id,Id>) branches.clone();
}
+ Id firstBranchRootId = null;
+
/* Mark all branch commits */
for (Entry<Id, Id> entry : tmpBranches.entrySet()) {
- Id branchRootId = entry.getKey();
- Id branchHeadId = entry.getValue();
- while (!branchHeadId.equals(branchRootId)) {
- StoredCommit commit = getCommit(branchHeadId);
+ Id branchRevId = entry.getKey();
+ Id branchRootId = entry.getValue();
+ while (!branchRevId.equals(branchRootId)) {
+ StoredCommit commit = getCommit(branchRevId);
markCommit(commit);
- branchHeadId = commit.getParentId();
+ branchRevId = commit.getParentId();
+ }
+ if (firstBranchRootId == null || firstBranchRootId.compareTo(branchRootId) > 0) {
+ firstBranchRootId = branchRootId;
}
}
/* Mark all master commits till the first branch root id */
- if (!tmpBranches.isEmpty()) {
- Id firstBranchRootId = tmpBranches.keySet().iterator().next();
+ if (firstBranchRootId != null) {
StoredCommit commit = getHeadCommit();
for (;;) {
@@ -637,6 +663,8 @@ public class DefaultRevisionStore extend
if (!gcpm.markCommit(commit.getId())) {
return;
}
+ markedCommits++;
+
markNode(getNode(commit.getRootNodeId()));
}
@@ -650,6 +678,8 @@ public class DefaultRevisionStore extend
if (!gcpm.markNode(node.getId())) {
return;
}
+ markedNodes++;
+
Iterator<ChildNodeEntry> iter = node.getChildNodeEntries(0, -1);
while (iter.hasNext()) {
ChildNodeEntry c = iter.next();
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/RevisionStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/RevisionStore.java?rev=1376084&r1=1376083&r2=1376084&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/RevisionStore.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/RevisionStore.java Wed Aug 22 14:53:18 2012
@@ -64,12 +64,15 @@ public interface RevisionStore extends R
* @param branchRootId
* former branch root id, if this is a merge; otherwise
* {@code null}
+ * @return branchRevId
+ * current branch head, i.e. last commit on this branch,
+ * if this is a merge; otherwise {@code null}
* @return head commit id
* @throws Exception
* if an error occurs
* @see #lockHead()
*/
- Id /*id*/ putHeadCommit(PutToken token, MutableCommit commit, Id branchRootId) throws Exception;
+ Id /*id*/ putHeadCommit(PutToken token, MutableCommit commit, Id branchRootId, Id branchRevId) throws Exception;
/**
* Unlock the head.