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 mr...@apache.org on 2017/07/20 08:42:42 UTC
svn commit: r1802458 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/document/
test/java/org/apache/jackrabbit/oak/plugins/document/
Author: mreutegg
Date: Thu Jul 20 08:42:41 2017
New Revision: 1802458
URL: http://svn.apache.org/viewvc?rev=1802458&view=rev
Log:
OAK-6477: RevisionGC metrics for DocumentNodeStore
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java (with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java (with props)
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsMBean.java (with props)
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java (with props)
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/DocumentNodeStoreService.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.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=1802458&r1=1802457&r2=1802458&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 Thu Jul 20 08:42:41 2017
@@ -567,6 +567,7 @@ public final class DocumentNodeStore
this.asyncDelay = builder.getAsyncDelay();
this.versionGarbageCollector = new VersionGarbageCollector(
this, builder.createVersionGCSupport());
+ this.versionGarbageCollector.setStatisticsProvider(builder.getStatisticsProvider());
this.versionGarbageCollector.setGCMonitor(builder.getGCMonitor());
this.journalGarbageCollector = new JournalGarbageCollector(this);
this.referencedBlobs =
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=1802458&r1=1802457&r2=1802458&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 Thu Jul 20 08:42:41 2017
@@ -925,6 +925,11 @@ public class DocumentNodeStoreService {
addRegistration(registerMBean(whiteboard, RevisionGCMBean.class, revisionGC,
RevisionGCMBean.TYPE, "Document node store revision garbage collection"));
+ addRegistration(registerMBean(whiteboard, RevisionGCStatsMBean.class,
+ store.getVersionGarbageCollector().getRevisionGCStats(),
+ RevisionGCStatsMBean.TYPE,
+ "Document node store revision garbage collection statistics"));
+
BlobStoreStats blobStoreStats = mkBuilder.getBlobStoreStats();
if (!customBlobStore && blobStoreStats != null) {
addRegistration(registerMBean(whiteboard,
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java?rev=1802458&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java Thu Jul 20 08:42:41 2017
@@ -0,0 +1,231 @@
+/*
+ * 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 javax.management.openmbean.CompositeData;
+
+import org.apache.jackrabbit.api.stats.TimeSeries;
+import org.apache.jackrabbit.oak.plugins.document.VersionGarbageCollector.VersionGCStats;
+import org.apache.jackrabbit.oak.stats.MeterStats;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.stats.TimerStats;
+import org.apache.jackrabbit.stats.TimeSeriesStatsUtil;
+
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
+import static org.apache.jackrabbit.oak.stats.StatsOptions.DEFAULT;
+import static org.apache.jackrabbit.oak.stats.StatsOptions.METRICS_ONLY;
+
+/**
+ * DocumentNodeStore revision garbage collection statistics.
+ */
+class RevisionGCStats implements RevisionGCStatsCollector, RevisionGCStatsMBean {
+
+ static final String RGC = "RevisionGC";
+ static final String READ_DOC = "READ_DOC";
+ static final String DELETE_DOC = "DELETE_DOC";
+ static final String DELETE_LEAF_DOC = "DELETE_LEAF_DOC";
+ static final String DELETE_SPLIT_DOC = "DELETE_SPLIT_DOC";
+ static final String DELETE_INT_SPLIT_DOC = "DELETE_INT_SPLIT_DOC";
+ static final String RESET_DELETED_FLAG = "RESET_DELETED_FLAG";
+
+ static final String ACTIVE_TIMER = "ACTIVE_TIMER";
+ static final String READ_DOC_TIMER = "READ_DOC_TIMER";
+ static final String CHECK_DELETED_TIMER = "CHECK_DELETED_TIMER";
+ static final String SORT_IDS_TIMER = "SORT_IDS_TIMER";
+ static final String RESET_DELETED_FLAG_TIMER = "RESET_DELETED_FLAG_TIMER";
+ static final String DELETE_DOC_TIMER = "DELETE_DOC_TIMER";
+ static final String DELETE_SPLIT_DOC_TIMER = "DELETE_SPLIT_DOC_TIMER";
+
+ private final StatisticsProvider provider;
+
+ private final MeterStats readDoc;
+ private final MeterStats deletedDoc;
+ private final MeterStats deletedLeafDoc;
+ private final MeterStats deletedSplitDoc;
+ private final MeterStats deletedIntSplitDoc;
+ private final MeterStats resetDeletedFlag;
+
+ private final TimerStats activeTimer;
+ private final TimerStats readDocTimer;
+ private final TimerStats checkDeletedTimer;
+ private final TimerStats sortIdsTimer;
+ private final TimerStats resetDeletedFlagTimer;
+ private final TimerStats deletedDocTimer;
+ private final TimerStats deletedSplitDocTimer;
+
+ RevisionGCStats(StatisticsProvider provider) {
+ this.provider = provider;
+
+ readDoc = meter(provider, READ_DOC);
+ deletedDoc = meter(provider, DELETE_DOC);
+ deletedLeafDoc = meter(provider, DELETE_LEAF_DOC);
+ deletedSplitDoc = meter(provider, DELETE_SPLIT_DOC);
+ deletedIntSplitDoc = meter(provider, DELETE_INT_SPLIT_DOC);
+ resetDeletedFlag = meter(provider, RESET_DELETED_FLAG);
+
+ activeTimer = timer(provider, ACTIVE_TIMER);
+ readDocTimer = timer(provider, READ_DOC_TIMER);
+ checkDeletedTimer = timer(provider, CHECK_DELETED_TIMER);
+ sortIdsTimer = timer(provider, SORT_IDS_TIMER);
+ resetDeletedFlagTimer = timer(provider, RESET_DELETED_FLAG_TIMER);
+ deletedDocTimer = timer(provider, DELETE_DOC_TIMER);
+ deletedSplitDocTimer = timer(provider, DELETE_SPLIT_DOC_TIMER);
+ }
+
+ //---------------------< RevisionGCStatsCollector >-------------------------
+
+ @Override
+ public void documentRead() {
+ readDoc.mark();
+ }
+
+ @Override
+ public void documentsDeleted(long numDocs) {
+ deletedDoc.mark(numDocs);
+
+ }
+
+ @Override
+ public void leafDocumentsDeleted(long numDocs) {
+ deletedDoc.mark(numDocs);
+ deletedLeafDoc.mark(numDocs);
+ }
+
+ @Override
+ public void splitDocumentsDeleted(long numDocs) {
+ deletedDoc.mark(numDocs);
+ deletedSplitDoc.mark(numDocs);
+
+ }
+
+ @Override
+ public void intermediateSplitDocumentsDeleted(long numDocs) {
+ deletedIntSplitDoc.mark(numDocs);
+ }
+
+ @Override
+ public void deletedOnceFlagReset() {
+ resetDeletedFlag.mark();
+ }
+
+ @Override
+ public void finished(VersionGCStats stats) {
+ activeTimer.update(stats.active.elapsed(MICROSECONDS), MICROSECONDS);
+ readDocTimer.update(stats.collectDeletedDocsElapsed, MICROSECONDS);
+ checkDeletedTimer.update(stats.checkDeletedDocsElapsed, MICROSECONDS);
+ deletedDocTimer.update(stats.deleteDeletedDocsElapsed, MICROSECONDS);
+ deletedSplitDocTimer.update(stats.collectAndDeleteSplitDocsElapsed, MICROSECONDS);
+ sortIdsTimer.update(stats.sortDocIdsElapsed, MICROSECONDS);
+ resetDeletedFlagTimer.update(stats.updateResurrectedDocumentsElapsed, MICROSECONDS);
+ }
+
+
+ //------------------------< RevisionGCStatsMBean >--------------------------
+
+ @Override
+ public long getReadDocCount() {
+ return readDoc.getCount();
+ }
+
+ @Override
+ public long getDeletedDocCount() {
+ return deletedDoc.getCount();
+ }
+
+ @Override
+ public long getDeletedLeafDocCount() {
+ return deletedLeafDoc.getCount();
+ }
+
+ @Override
+ public long getDeletedSplitDocCount() {
+ return deletedSplitDoc.getCount();
+ }
+
+ @Override
+ public long getDeletedIntSplitDocCount() {
+ return deletedIntSplitDoc.getCount();
+ }
+
+ @Override
+ public long getResetDeletedFlagCount() {
+ return resetDeletedFlag.getCount();
+ }
+
+ @Override
+ public CompositeData getReadDocHistory() {
+ return getTimeSeriesData(READ_DOC,
+ "Documents read by RevisionGC");
+ }
+
+ @Override
+ public CompositeData getDeletedDocHistory() {
+ return getTimeSeriesData(DELETE_DOC,
+ "Documents deleted by RevisionGC");
+ }
+
+ @Override
+ public CompositeData getDeletedLeafDocHistory() {
+ return getTimeSeriesData(DELETE_LEAF_DOC,
+ "Leaf documents deleted by RevisionGC");
+ }
+
+ @Override
+ public CompositeData getDeletedSplitDocHistory() {
+ return getTimeSeriesData(DELETE_SPLIT_DOC,
+ "Split documents deleted by RevisionGC");
+ }
+
+ @Override
+ public CompositeData getDeletedIntSplitDocHistory() {
+ return getTimeSeriesData(DELETE_INT_SPLIT_DOC,
+ "Intermediate split documents deleted by RevisionGC");
+ }
+
+ @Override
+ public CompositeData getResetDeletedFlagHistory() {
+ return getTimeSeriesData(RESET_DELETED_FLAG,
+ "Deleted once flags reset by RevisionGC");
+ }
+
+
+ //----------------------------< internal >----------------------------------
+
+ private static MeterStats meter(StatisticsProvider provider,
+ String name) {
+ return provider.getMeter(qualifiedName(name), DEFAULT);
+ }
+
+ private static TimerStats timer(StatisticsProvider provider,
+ String name) {
+ return provider.getTimer(qualifiedName(name), METRICS_ONLY);
+ }
+
+ private static String qualifiedName(String metricName) {
+ return RGC + "." + metricName;
+ }
+
+ private CompositeData getTimeSeriesData(String name, String desc) {
+ return TimeSeriesStatsUtil.asCompositeData(getTimeSeries(name), desc);
+ }
+
+ private TimeSeries getTimeSeries(String name) {
+ return provider.getStats().getTimeSeries(qualifiedName(name), true);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStats.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java?rev=1802458&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java Thu Jul 20 08:42:41 2017
@@ -0,0 +1,42 @@
+/*
+ * 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.plugins.document.VersionGarbageCollector.VersionGCStats;
+
+/**
+ * Collector interface for DocumentNodeStore revision garbage collection
+ * statistics.
+ */
+public interface RevisionGCStatsCollector {
+
+ void documentRead();
+
+ void documentsDeleted(long numDocs);
+
+ void leafDocumentsDeleted(long numDocs);
+
+ void splitDocumentsDeleted(long numDocs);
+
+ void intermediateSplitDocumentsDeleted(long numDocs);
+
+ void deletedOnceFlagReset();
+
+ void finished(VersionGCStats stats);
+}
\ No newline at end of file
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsCollector.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsMBean.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsMBean.java?rev=1802458&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsMBean.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsMBean.java Thu Jul 20 08:42:41 2017
@@ -0,0 +1,53 @@
+/*
+ * 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 javax.management.openmbean.CompositeData;
+
+/**
+ * MBean exposing DocumentNodeStore revision garbage collection statistics.
+ */
+public interface RevisionGCStatsMBean {
+
+ String TYPE = "RevisionGCStats";
+
+ long getReadDocCount();
+
+ long getDeletedDocCount();
+
+ long getDeletedLeafDocCount();
+
+ long getDeletedSplitDocCount();
+
+ long getDeletedIntSplitDocCount();
+
+ long getResetDeletedFlagCount();
+
+ CompositeData getReadDocHistory();
+
+ CompositeData getDeletedDocHistory();
+
+ CompositeData getDeletedLeafDocHistory();
+
+ CompositeData getDeletedSplitDocHistory();
+
+ CompositeData getDeletedIntSplitDocHistory();
+
+ CompositeData getResetDeletedFlagHistory();
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsMBean.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=1802458&r1=1802457&r2=1802458&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 Thu Jul 20 08:42:41 2017
@@ -52,6 +52,7 @@ import org.apache.jackrabbit.oak.spi.gc.
import org.apache.jackrabbit.oak.spi.gc.GCMonitor;
import org.apache.jackrabbit.oak.stats.Clock;
import org.apache.jackrabbit.oak.commons.TimeDurationFormatter;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -109,6 +110,7 @@ public class VersionGarbageCollector {
private final AtomicReference<GCJob> collector = newReference();
private VersionGCOptions options;
private GCMonitor gcMonitor = GCMonitor.EMPTY;
+ private RevisionGCStats gcStats = new RevisionGCStats(StatisticsProvider.NOOP);
VersionGarbageCollector(DocumentNodeStore nodeStore,
VersionGCSupport gcSupport) {
@@ -118,6 +120,15 @@ public class VersionGarbageCollector {
this.options = new VersionGCOptions();
}
+ void setStatisticsProvider(StatisticsProvider provider) {
+ this.gcStats = new RevisionGCStats(provider);
+ }
+
+ @Nonnull
+ RevisionGCStats getRevisionGCStats() {
+ return gcStats;
+ }
+
public VersionGCStats gc(long maxRevisionAge, TimeUnit unit) throws IOException {
long maxRevisionAgeInMillis = unit.toMillis(maxRevisionAge);
TimeInterval maxRunTime = new TimeInterval(nodeStore.getClock().getTime(), Long.MAX_VALUE);
@@ -145,6 +156,7 @@ public class VersionGarbageCollector {
averageDurationMs = ((averageDurationMs * (overall.iterationCount - 1))
+ stats.active.elapsed(TimeUnit.MILLISECONDS)) / overall.iterationCount;
}
+ gcStats.finished(overall);
return overall;
} finally {
overall.active.stop();
@@ -482,7 +494,11 @@ public class VersionGarbageCollector {
RevisionVector sweepRevisions,
Recommendations rec) {
if (phases.start(GCPhase.SPLITS_CLEANUP)) {
+ int splitDocGCCount = phases.stats.splitDocGCCount;
+ int intermediateSplitDocGCCount = phases.stats.intermediateSplitDocGCCount;
versionStore.deleteSplitDocuments(GC_TYPES, sweepRevisions, rec.scope.toMs, phases.stats);
+ gcStats.splitDocumentsDeleted(phases.stats.splitDocGCCount - splitDocGCCount);
+ gcStats.intermediateSplitDocumentsDeleted(phases.stats.intermediateSplitDocGCCount - intermediateSplitDocGCCount);
phases.stop(GCPhase.SPLITS_CLEANUP);
}
}
@@ -615,6 +631,7 @@ public class VersionGarbageCollector {
*/
boolean possiblyDeleted(NodeDocument doc)
throws IOException {
+ gcStats.documentRead();
// construct an id that also contains
// the _modified time of the document
String id = doc.getId() + "/" + doc.getModified();
@@ -652,7 +669,7 @@ public class VersionGarbageCollector {
void removeDocuments(VersionGCStats stats) throws IOException {
removeLeafDocuments(stats);
stats.deletedDocGCCount += removeDeletedDocuments(
- getDocIdsToDelete(), getDocIdsToDeleteSize(), "(other)");
+ getDocIdsToDelete(), getDocIdsToDeleteSize(), false, "(other)");
// FIXME: this is incorrect because that method also removes intermediate docs
stats.splitDocGCCount += removeDeletedPreviousDocuments();
}
@@ -667,7 +684,7 @@ public class VersionGarbageCollector {
void removeLeafDocuments(VersionGCStats stats) throws IOException {
int removeCount = removeDeletedDocuments(
- getLeafDocIdsToDelete(), getLeafDocIdsToDeleteSize(), "(leaf)");
+ getLeafDocIdsToDelete(), getLeafDocIdsToDeleteSize(), true, "(leaf)");
leafDocIdsToDelete.clear();
stats.deletedLeafDocGCCount += removeCount;
stats.deletedDocGCCount += removeCount;
@@ -798,7 +815,11 @@ public class VersionGarbageCollector {
private int removeDeletedDocuments(Iterator<String> docIdsToDelete,
long numDocuments,
+ boolean leaves,
String label) throws IOException {
+ if (numDocuments == 0) {
+ return 0;
+ }
monitor.info("Proceeding to delete [{}] documents [{}]", numDocuments, label);
Iterator<List<String>> idListItr = partition(docIdsToDelete, DELETE_BATCH_SIZE);
@@ -842,6 +863,11 @@ public class VersionGarbageCollector {
deletedCount += nRemoved;
log.debug("Deleted [{}] documents so far", deletedCount);
+ if (leaves) {
+ gcStats.leafDocumentsDeleted(deletedCount);
+ } else {
+ gcStats.documentsDeleted(deletedCount);
+ }
if (deletedCount + recreatedCount - lastLoggedCount >= PROGRESS_BATCH_SIZE) {
lastLoggedCount = deletedCount + recreatedCount;
@@ -872,6 +898,7 @@ public class VersionGarbageCollector {
NodeDocument r = ds.findAndUpdate(Collection.NODES, up);
if (r != null) {
updateCount += 1;
+ gcStats.deletedOnceFlagReset();
}
} catch (IllegalArgumentException ex) {
monitor.warn("Invalid _modified suffix for {}", s);
@@ -888,7 +915,11 @@ public class VersionGarbageCollector {
}
private int removeDeletedPreviousDocuments() throws IOException {
- monitor.info("Proceeding to delete [{}] previous documents", getNumPreviousDocuments());
+ long num = getNumPreviousDocuments();
+ if (num == 0) {
+ return 0;
+ }
+ monitor.info("Proceeding to delete [{}] previous documents", num);
int deletedCount = 0;
int lastLoggedCount = 0;
@@ -907,6 +938,7 @@ public class VersionGarbageCollector {
ds.remove(NODES, deletionBatch);
log.debug("Deleted [{}] previous documents so far", deletedCount);
+ gcStats.splitDocumentsDeleted(deletedCount);
if (deletedCount - lastLoggedCount >= PROGRESS_BATCH_SIZE) {
lastLoggedCount = deletedCount;
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java?rev=1802458&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java Thu Jul 20 08:42:41 2017
@@ -0,0 +1,144 @@
+/*
+ * 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 java.util.concurrent.ScheduledExecutorService;
+
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.Timer;
+
+import org.apache.jackrabbit.oak.commons.concurrent.ExecutorCloser;
+import org.apache.jackrabbit.oak.plugins.document.VersionGarbageCollector.VersionGCStats;
+import org.apache.jackrabbit.oak.plugins.metric.MetricStatisticsProvider;
+import org.junit.After;
+import org.junit.Test;
+
+import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static org.apache.jackrabbit.oak.plugins.document.RevisionGCStats.RGC;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class RevisionGCStatsTest {
+
+ private ScheduledExecutorService executor = newSingleThreadScheduledExecutor();
+ private MetricStatisticsProvider statsProvider =
+ new MetricStatisticsProvider(getPlatformMBeanServer(), executor);
+ private RevisionGCStats stats = new RevisionGCStats(statsProvider);
+
+ @After
+ public void shutDown(){
+ statsProvider.close();
+ new ExecutorCloser(executor).close();
+ }
+
+ @Test
+ public void getReadDocCount() {
+ Meter m = getMeter(RevisionGCStats.READ_DOC);
+ long count = m.getCount();
+ stats.documentRead();
+ assertEquals(count + 1, m.getCount());
+ assertEquals(count + 1, stats.getReadDocCount());
+ }
+
+ @Test
+ public void getDeletedDocCount() {
+ Meter m = getMeter(RevisionGCStats.DELETE_DOC);
+ long count = m.getCount();
+ stats.documentsDeleted(17);
+ assertEquals(count + 17, m.getCount());
+ assertEquals(count + 17, stats.getDeletedDocCount());
+ }
+
+ @Test
+ public void getDeletedLeafDocCount() {
+ Meter m = getMeter(RevisionGCStats.DELETE_LEAF_DOC);
+ long count = m.getCount();
+ stats.leafDocumentsDeleted(17);
+ assertEquals(count + 17, m.getCount());
+ assertEquals(count + 17, stats.getDeletedLeafDocCount());
+ }
+
+ @Test
+ public void getDeletedSplitDocCount() {
+ Meter m = getMeter(RevisionGCStats.DELETE_SPLIT_DOC);
+ long count = m.getCount();
+ stats.splitDocumentsDeleted(17);
+ assertEquals(count + 17, m.getCount());
+ assertEquals(count + 17, stats.getDeletedSplitDocCount());
+ }
+
+ @Test
+ public void getDeletedIntSplitDocCount() {
+ Meter m = getMeter(RevisionGCStats.DELETE_INT_SPLIT_DOC);
+ long count = m.getCount();
+ stats.intermediateSplitDocumentsDeleted(17);
+ assertEquals(count + 17, m.getCount());
+ assertEquals(count + 17, stats.getDeletedIntSplitDocCount());
+ }
+
+ @Test
+ public void getResetDeletedFlagCount() {
+ Meter m = getMeter(RevisionGCStats.RESET_DELETED_FLAG);
+ long count = m.getCount();
+ stats.deletedOnceFlagReset();
+ assertEquals(count + 1, m.getCount());
+ assertEquals(count + 1, stats.getResetDeletedFlagCount());
+ }
+
+ @Test
+ public void timers() {
+ VersionGCStats vgcs = new VersionGCStats();
+ vgcs.collectDeletedDocsElapsed = MILLISECONDS.toMicros(2);
+ vgcs.checkDeletedDocsElapsed = MILLISECONDS.toMicros(3);
+ vgcs.deleteDeletedDocsElapsed = MILLISECONDS.toMicros(5);
+ vgcs.collectAndDeleteSplitDocsElapsed = MILLISECONDS.toMicros(7);
+ vgcs.sortDocIdsElapsed = MILLISECONDS.toMicros(11);
+ vgcs.updateResurrectedDocumentsElapsed = MILLISECONDS.toMicros(13);
+ vgcs.active.start();
+ while (vgcs.active.elapsed(MILLISECONDS) < 5) {
+ // busy wait
+ assertTrue(vgcs.active.isRunning());
+ }
+ vgcs.active.stop();
+
+ stats.finished(vgcs);
+ assertTimer(vgcs.active.elapsed(MILLISECONDS), RevisionGCStats.ACTIVE_TIMER);
+ assertTimer(2, RevisionGCStats.READ_DOC_TIMER);
+ assertTimer(3, RevisionGCStats.CHECK_DELETED_TIMER);
+ assertTimer(5, RevisionGCStats.DELETE_DOC_TIMER);
+ assertTimer(7, RevisionGCStats.DELETE_SPLIT_DOC_TIMER);
+ assertTimer(11, RevisionGCStats.SORT_IDS_TIMER);
+ assertTimer(13, RevisionGCStats.RESET_DELETED_FLAG_TIMER);
+ }
+
+ private void assertTimer(long expected, String name) {
+ assertEquals(expected, NANOSECONDS.toMillis(getTimer(name).getSnapshot().getMax()));
+ }
+
+ private Timer getTimer(String name) {
+ return statsProvider.getRegistry().getTimers().get(RGC + "." + name);
+ }
+
+ private Meter getMeter(String name) {
+ return statsProvider.getRegistry().getMeters().get(RGC + "." + name);
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionGCStatsTest.java
------------------------------------------------------------------------------
svn:eol-style = native