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 jo...@apache.org on 2024/06/26 14:11:22 UTC

(jackrabbit-oak) branch trunk updated: OAK-10915: Avoid deleting expired checkpoints when running FullGC on a read-only NodeStore

This is an automated email from the ASF dual-hosted git repository.

joscorbe pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/trunk by this push:
     new f804a762ee OAK-10915: Avoid deleting expired checkpoints when running FullGC on a read-only NodeStore
f804a762ee is described below

commit f804a762eea9a4bb9299ae23fc3a00508da81350
Author: José Andrés Cordero Benítez <Jo...@users.noreply.github.com>
AuthorDate: Wed Jun 26 16:11:18 2024 +0200

    OAK-10915: Avoid deleting expired checkpoints when running FullGC on a read-only NodeStore
---
 .../oak/plugins/document/Checkpoints.java           | 21 ++++++++++++++++-----
 .../plugins/document/VersionGCRecommendations.java  |  8 ++++----
 .../plugins/document/VersionGarbageCollector.java   |  6 ++++--
 .../oak/plugins/document/VersionGCTest.java         | 16 ++++++++--------
 4 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java
index e57a75258d..cb24d65510 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java
@@ -109,16 +109,15 @@ class Checkpoints {
     }
 
     /**
-     * Returns the oldest valid checkpoint registered.
-     *
-     * <p>It also performs cleanup of expired checkpoint
+     * Returns the oldest valid checkpoint registered
+     * @param performCleanup if true, it will perform cleanup of expired checkpoint
      *
      * @return oldest valid checkpoint registered. Might return null if no valid
      * checkpoint found
      */
     @SuppressWarnings("unchecked")
     @Nullable
-    public Revision getOldestRevisionToKeep() {
+    public Revision getOldestRevisionToKeep(boolean performCleanup) {
         //Get uncached doc
         SortedMap<Revision, Info> checkpoints = getCheckpoints();
 
@@ -145,7 +144,7 @@ class Checkpoints {
             }
         }
 
-        if (op.hasChanges()) {
+        if (performCleanup && op.hasChanges()) {
             try {
                 store.findAndUpdate(Collection.SETTINGS, op);
                 LOG.debug("Purged {} expired checkpoints", op.getChanges().size());
@@ -158,6 +157,18 @@ class Checkpoints {
         return lastAliveRevision;
     }
 
+    /**
+     * Returns the oldest valid checkpoint registered.
+     *
+     * <p>It also performs cleanup of expired checkpoint
+     *
+     * @return oldest valid checkpoint registered. Might return null if no valid
+     * checkpoint found
+     */
+    public Revision getOldestRevisionToKeep() {
+        return getOldestRevisionToKeep(true);
+    }
+
     @SuppressWarnings("unchecked")
     @NotNull
     SortedMap<Revision, Info> getCheckpoints() {
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGCRecommendations.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGCRecommendations.java
index 6ee38b4925..1439bbfdf7 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGCRecommendations.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGCRecommendations.java
@@ -107,9 +107,9 @@ public class VersionGCRecommendations {
      * @param fullGCEnabled      whether fullGC is enabled or not
      * @param isFullGCDryRun     whether fullGC is running in dryRun mode or not
      */
-    VersionGCRecommendations(long maxRevisionAgeMs, Checkpoints checkpoints, Clock clock, VersionGCSupport vgc,
-                                    VersionGCOptions options, GCMonitor gcMonitor, boolean fullGCEnabled,
-                                    boolean isFullGCDryRun) {
+    VersionGCRecommendations(long maxRevisionAgeMs, Checkpoints checkpoints, boolean checkpointCleanup, Clock clock,
+                                    VersionGCSupport vgc, VersionGCOptions options, GCMonitor gcMonitor,
+                                    boolean fullGCEnabled, boolean isFullGCDryRun) {
         boolean ignoreDueToCheckPoint;
         boolean ignoreFullGCDueToCheckPoint;
         long deletedOnceCount = 0;
@@ -223,7 +223,7 @@ public class VersionGCRecommendations {
         }
 
         //Check for any registered checkpoint which prevent the GC from running
-        Revision checkpoint = checkpoints.getOldestRevisionToKeep();
+        Revision checkpoint = checkpoints.getOldestRevisionToKeep(checkpointCleanup);;
 
         final GCResult gcResult = getResult(options, checkpoint, clock, RGC, scope);
         scope = gcResult.gcScope;
diff --git a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
index 0e81cccc1c..730f46fa8b 100644
--- a/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
+++ b/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
@@ -402,7 +402,8 @@ public class VersionGarbageCollector {
         long maxRevisionAgeInMillis = unit.toMillis(maxRevisionAge);
         long now = nodeStore.getClock().getTime();
         VersionGCRecommendations rec = new VersionGCRecommendations(maxRevisionAgeInMillis, nodeStore.getCheckpoints(),
-                nodeStore.getClock(), versionStore, options, gcMonitor, fullGCEnabled, isFullGCDryRun);
+                !nodeStore.isReadOnlyMode(), nodeStore.getClock(), versionStore, options, gcMonitor, fullGCEnabled,
+                isFullGCDryRun);
         int estimatedIterations = -1;
         if (rec.suggestedIntervalMs > 0) {
             estimatedIterations = (int)Math.ceil((double) (now - rec.scope.toMs) / rec.suggestedIntervalMs);
@@ -782,7 +783,8 @@ public class VersionGarbageCollector {
             VersionGCStats stats = new VersionGCStats();
             stats.active.start();
             VersionGCRecommendations rec = new VersionGCRecommendations(maxRevisionAgeInMillis, nodeStore.getCheckpoints(),
-                    nodeStore.getClock(), versionStore, options, gcMonitor, fullGCEnabled, isFullGCDryRun);
+                    !nodeStore.isReadOnlyMode(), nodeStore.getClock(), versionStore, options, gcMonitor, fullGCEnabled,
+                    isFullGCDryRun);
             GCPhases phases = new GCPhases(cancel, stats, gcMonitor);
             try {
                 if (!isFullGCDryRun) {
diff --git a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java
index ce87e87d0c..857813a503 100644
--- a/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java
+++ b/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/VersionGCTest.java
@@ -373,8 +373,8 @@ public class VersionGCTest {
 
         VersionGCSupport localgcsupport = fakeVersionGCSupport(ns.getDocumentStore(), oneYearAgo, twelveTimesTheLimit);
 
-        VersionGCRecommendations rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), ns.getClock(), localgcsupport,
-                options, new TestGCMonitor(), false, false);
+        VersionGCRecommendations rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), true, ns.getClock(),
+                localgcsupport, options, new TestGCMonitor(), false, false);
 
         // should select a duration of roughly one month
         long duration= rec.scope.getDurationMs();
@@ -387,8 +387,8 @@ public class VersionGCTest {
         rec.evaluate(stats);
         assertTrue(stats.needRepeat);
 
-        rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), ns.getClock(), localgcsupport, options,
-                new TestGCMonitor(), false, false);
+        rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), true, ns.getClock(), localgcsupport,
+                options, new TestGCMonitor(), false, false);
 
         // new duration should be half
         long nduration = rec.scope.getDurationMs();
@@ -416,8 +416,8 @@ public class VersionGCTest {
 
         // loop until the recommended interval is at 60s (precisionMS)
         do {
-            rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), ns.getClock(), localgcsupport, options,
-                    testmonitor, false, false);
+            rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), true, ns.getClock(), localgcsupport,
+                    options, testmonitor, false, false);
             stats = new VersionGCStats();
             stats.limitExceeded = true;
             rec.evaluate(stats);
@@ -433,8 +433,8 @@ public class VersionGCTest {
             int deleted = (int) (rec.scope.getDurationMs() / TimeUnit.SECONDS.toMillis(1));
             deletedCount -= deleted;
             localgcsupport = fakeVersionGCSupport(ns.getDocumentStore(), oldestDeleted, deletedCount);
-            rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), ns.getClock(), localgcsupport, options,
-                    testmonitor, false, false);
+            rec = new VersionGCRecommendations(secondsPerDay, ns.getCheckpoints(), true, ns.getClock(), localgcsupport,
+                    options, testmonitor, false, false);
             stats = new VersionGCStats();
             stats.limitExceeded = false;
             stats.deletedDocGCCount = deleted;