Author: mreutegg
Date: Mon Jul 24 09:45:09 2017
New Revision: 1802778
URL: http://svn.apache.org/viewvc?rev=1802778&view=rev
Log:
OAK-3710: Continuous revision GC
Redirect RevisionGC log messages to DEBUG level when continuous revision GC is
enabled
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/QuietGCMonitor.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1802778&r1=1802777&r2=1802778&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
Mon Jul 24 09:45:09 2017
@@ -96,6 +96,7 @@ import org.apache.jackrabbit.oak.spi.blo
import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore;
import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
+import org.apache.jackrabbit.oak.spi.gc.LoggingGCMonitor;
import org.apache.jackrabbit.oak.stats.Clock;
import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.slf4j.Logger;
@@ -601,7 +602,8 @@ public class DocumentMK {
new JournalPropertyHandlerFactory();
private int updateLimit = UPDATE_LIMIT;
private int commitValueCacheSize = 10000;
- private GCMonitor gcMonitor = GCMonitor.EMPTY;
+ private GCMonitor gcMonitor = new LoggingGCMonitor(
+ LoggerFactory.getLogger(VersionGarbageCollector.class));
public Builder() {
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java?rev=1802778&r1=1802777&r2=1802778&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreService.java
Mon Jul 24 09:45:09 2017
@@ -19,6 +19,7 @@
package org.apache.jackrabbit.oak.plugins.document;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Lists.newArrayList;
import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toBoolean;
import static org.apache.jackrabbit.oak.commons.PropertiesUtil.toInteger;
@@ -90,7 +91,10 @@ import org.apache.jackrabbit.oak.spi.blo
import org.apache.jackrabbit.oak.spi.blob.GarbageCollectableBlobStore;
import org.apache.jackrabbit.oak.spi.blob.stats.BlobStoreStatsMBean;
import org.apache.jackrabbit.oak.spi.commit.BackgroundObserverMBean;
+import org.apache.jackrabbit.oak.spi.gc.DelegatingGCMonitor;
+import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
import org.apache.jackrabbit.oak.spi.gc.GCMonitorTracker;
+import org.apache.jackrabbit.oak.spi.gc.LoggingGCMonitor;
import org.apache.jackrabbit.oak.spi.state.Clusterable;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.apache.jackrabbit.oak.spi.state.NodeStoreProvider;
@@ -133,6 +137,7 @@ public class DocumentNodeStoreService {
private static final boolean DEFAULT_SO_KEEP_ALIVE = false;
private static final String DEFAULT_PERSISTENT_CACHE = "cache,binary=0";
private static final String DEFAULT_JOURNAL_CACHE = "diff-cache";
+ private static final boolean DEFAULT_CONTINUOUS_RGC = false;
private static final String PREFIX = "oak.documentstore.";
private static final String DESCRIPTION = "oak.nodestore.description";
@@ -338,7 +343,7 @@ public class DocumentNodeStoreService {
)
public static final String PROP_VER_GC_MAX_AGE = "versionGcMaxAgeInSecs";
- @Property (boolValue = false,
+ @Property (boolValue = DEFAULT_CONTINUOUS_RGC,
label = "Continuous Version GC Mode",
description = "Run Version GC continuously as a background task.")
public static final String PROP_VER_GC_CONTINUOUS = "versionGCContinuous";
@@ -581,7 +586,16 @@ public class DocumentNodeStoreService {
final GCMonitorTracker gcMonitor = new GCMonitorTracker();
gcMonitor.start(whiteboard);
closer.register(asCloseable(gcMonitor));
- mkBuilder.setGCMonitor(gcMonitor);
+ Logger vgcLogger =
LoggerFactory.getLogger(VersionGarbageCollector.class);
+ GCMonitor loggingGCMonitor;
+ if (isContinuousRevisionGC()) {
+ // log less chatty with continuous RevisionGC
+ loggingGCMonitor = new QuietGCMonitor(vgcLogger);
+ } else {
+ loggingGCMonitor = new LoggingGCMonitor(vgcLogger);
+ }
+ mkBuilder.setGCMonitor(new DelegatingGCMonitor(
+ newArrayList(gcMonitor, loggingGCMonitor)));
nodeStore = mkBuilder.getNodeStore();
@@ -680,6 +694,10 @@ public class DocumentNodeStoreService {
return prop(PROP_ROLE) != null;
}
+ private boolean isContinuousRevisionGC() {
+ return toBoolean(prop(PROP_VER_GC_CONTINUOUS), DEFAULT_CONTINUOUS_RGC);
+ }
+
private void registerNodeStoreProvider(final NodeStore ns) {
Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put(NodeStoreProvider.ROLE, prop(PROP_ROLE));
@@ -982,7 +1000,7 @@ public class DocumentNodeStoreService {
}
private void registerVersionGCJob(final DocumentNodeStore nodeStore) {
- if (toBoolean(context.getProperties().get(PROP_VER_GC_CONTINUOUS),
false)) {
+ if (isContinuousRevisionGC()) {
final long versionGcMaxAgeInSecs =
toLong(prop(PROP_VER_GC_MAX_AGE), DEFAULT_VER_GC_MAX_AGE);
addRegistration(WhiteboardUtils.scheduleWithFixedDelay(whiteboard,
new RevisionGCJob(nodeStore, versionGcMaxAgeInSecs, log),
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/QuietGCMonitor.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/QuietGCMonitor.java?rev=1802778&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/QuietGCMonitor.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/QuietGCMonitor.java
Mon Jul 24 09:45:09 2017
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.document;
+
+import org.apache.jackrabbit.oak.spi.gc.LoggingGCMonitor;
+import org.slf4j.Logger;
+
+/**
+ * A variant of a logging GCMonitor that emits debug log messages for
+ * {@link #info(String, Object...)} calls.
+ */
+class QuietGCMonitor extends LoggingGCMonitor {
+
+ private final Logger log;
+
+ QuietGCMonitor(Logger log) {
+ super(log);
+ this.log = log;
+ }
+
+ @Override
+ public void info(String message, Object... arguments) {
+ log.debug(message, arguments);
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/QuietGCMonitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java?rev=1802778&r1=1802777&r2=1802778&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
Mon Jul 24 09:45:09 2017
@@ -142,7 +142,7 @@ public class VersionGarbageCollector {
try {
long averageDurationMs = 0;
while (maxRunTime.contains(nodeStore.getClock().getTime() +
averageDurationMs)) {
- log.info("start {}. run (avg duration {} sec)",
+ gcMonitor.info("Start {}. run (avg duration {} sec)",
overall.iterationCount + 1, averageDurationMs /
1000.0);
VersionGCStats stats = job.run();
@@ -162,7 +162,7 @@ public class VersionGarbageCollector {
overall.active.stop();
collector.set(null);
if (overall.iterationCount > 1) {
- log.info("Revision garbage collection finished after {}
iterations - aggregate statistics: {}",
+ gcMonitor.info("Revision garbage collection finished after
{} iterations - aggregate statistics: {}",
overall.iterationCount, overall);
}
}
@@ -271,7 +271,7 @@ public class VersionGarbageCollector {
String timings;
String fmt = "timeToCollectDeletedDocs=%s,
timeToCheckDeletedDocs=%s, timeToSortDocIds=%s,
timeTakenToUpdateResurrectedDocs=%s, timeTakenToDeleteDeletedDocs=%s,
timeTakenToCollectAndDeleteSplitDocs=%s";
- // aggregrated timings?
+ // aggregated timings?
if (iterationCount > 0) {
timings = String.format(fmt,
df.format(collectDeletedDocsElapsed, MICROSECONDS),
df.format(checkDeletedDocsElapsed, MICROSECONDS),
df.format(sortDocIdsElapsed, MICROSECONDS),
@@ -435,7 +435,7 @@ public class VersionGarbageCollector {
GCMonitor gcMonitor) {
this.maxRevisionAgeMillis = maxRevisionAgeMillis;
this.options = options;
- VersionGCMonitor vgcm = new VersionGCMonitor();
+ GCMessageTracker vgcm = new GCMessageTracker();
this.status = vgcm;
this.monitor = new DelegatingGCMonitor(Lists.newArrayList(vgcm,
gcMonitor));
this.monitor.updateStatus(STATUS_INITIALIZING);
@@ -1117,7 +1117,7 @@ public class VersionGarbageCollector {
if (stats.limitExceeded) {
// if the limit was exceeded, slash the recommended interval
in half.
long nextDuration = Math.max(precisionMs,
scope.getDurationMs() / 2);
- log.info("Limit {} documents exceeded, reducing next
collection interval to {} seconds",
+ gcMonitor.info("Limit {} documents exceeded, reducing next
collection interval to {} seconds",
this.maxCollect,
TimeUnit.MILLISECONDS.toSeconds(nextDuration));
setLongSetting(SETTINGS_COLLECTION_REC_INTERVAL_PROP,
nextDuration);
stats.needRepeat = true;
@@ -1163,11 +1163,10 @@ public class VersionGarbageCollector {
}
/**
- * VersionGCMonitor is a partial implementation of GCMonitor because some
- * methods are specific to segment-tar. We use it primarily to keep track
- * of the last message issued by the GC job.
+ * GCMessageTracker is a partial implementation of GCMonitor. We use it to
+ * keep track of the last message issued by the GC job.
*/
- private static class VersionGCMonitor
+ private static class GCMessageTracker
extends GCMonitor.Empty
implements Supplier<String> {
@@ -1175,19 +1174,16 @@ public class VersionGarbageCollector {
@Override
public void info(String message, Object... arguments) {
- log.info(message, arguments);
lastMessage = arrayFormat(message, arguments).getMessage();
}
@Override
public void warn(String message, Object... arguments) {
- log.warn(message, arguments);
lastMessage = arrayFormat(message, arguments).getMessage();
}
@Override
public void error(String message, Exception e) {
- log.error(message, e);
lastMessage = message + " (" + e.getMessage() + ")";
}
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java?rev=1802778&r1=1802777&r2=1802778&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java
Mon Jul 24 09:45:09 2017
@@ -221,9 +221,10 @@ public class VersionGCTest {
gc.gc(1, TimeUnit.HOURS);
- assertEquals(2, infoMessages.size());
- assertTrue(infoMessages.get(0).startsWith("Looking at revisions"));
- assertTrue(infoMessages.get(1).startsWith("Revision garbage collection
finished"));
+ assertEquals(3, infoMessages.size());
+ assertTrue(infoMessages.get(0).startsWith("Start "));
+ assertTrue(infoMessages.get(1).startsWith("Looking at revisions"));
+ assertTrue(infoMessages.get(2).startsWith("Revision garbage collection
finished"));
}
private Future<VersionGCStats> gc() {