Author: amitj
Date: Tue Mar 13 05:27:11 2018
New Revision: 1826604

URL: http://svn.apache.org/viewvc?rev=1826604&view=rev
Log:
OAK-7209: Race condition can resurrect blobs during blob GC
Merge r1826532 from trunk

Modified:
    jackrabbit/oak/branches/1.8/   (props changed)
    
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTracker.java
    
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTrackerTest.java

Propchange: jackrabbit/oak/branches/1.8/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Mar 13 05:27:11 2018
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1820660-1820661,1820729,1820734,1820859,1820861,1820878,1820888,1820947,1821130,1821140-1821141,1821240,1821249,1821258,1821325,1821358,1821361-1821362,1821370,1821375,1821393,1821477,1821487,1821516,1821665,1821668,1821681,1822121,1822201,1822207,1822723,1822808,1822850,1822934,1823135,1823163,1823169,1824196,1824198,1824962,1825362,1825381,1825442,1825448,1825466,1825470,1825475,1825523,1825525,1825619-1825621,1825651,1825654,1825992,1826079,1826090,1826096,1826237,1826338
+/jackrabbit/oak/trunk:1820660-1820661,1820729,1820734,1820859,1820861,1820878,1820888,1820947,1821130,1821140-1821141,1821240,1821249,1821258,1821325,1821358,1821361-1821362,1821370,1821375,1821393,1821477,1821487,1821516,1821665,1821668,1821681,1822121,1822201,1822207,1822723,1822808,1822850,1822934,1823135,1823163,1823169,1824196,1824198,1824962,1825362,1825381,1825442,1825448,1825466,1825470,1825475,1825523,1825525,1825619-1825621,1825651,1825654,1825992,1826079,1826090,1826096,1826237,1826338,1826532
 /jackrabbit/trunk:1345480

Modified: 
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTracker.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.8/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTracker.java?rev=1826604&r1=1826603&r2=1826604&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTracker.java
 (original)
+++ 
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/main/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTracker.java
 Tue Mar 13 05:27:11 2018
@@ -144,8 +144,8 @@ public class BlobIdTracker implements Cl
     }
 
     @Override public void remove(File recs, Options options) throws 
IOException {
+        globalMerge();
         if (options == Options.ACTIVE_DELETION) {
-            globalMerge();
             deleteTracker.track(recs);
         }
         store.removeRecords(recs);
@@ -153,11 +153,13 @@ public class BlobIdTracker implements Cl
     }
 
     @Override public void remove(File recs) throws IOException {
+        globalMerge();
         store.removeRecords(recs);
         snapshot(true);
     }
 
     @Override public void remove(Iterator<String> recs) throws IOException {
+        globalMerge();
         store.removeRecords(recs);
         snapshot(true);
     }

Modified: 
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTrackerTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.8/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTrackerTest.java?rev=1826604&r1=1826603&r2=1826604&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTrackerTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.8/oak-blob-plugins/src/test/java/org/apache/jackrabbit/oak/plugins/blob/datastore/BlobIdTrackerTest.java
 Tue Mar 13 05:27:11 2018
@@ -124,7 +124,7 @@ public class BlobIdTrackerTest {
     @Test
     public void addSnapshotRemove() throws Exception {
         LOG.info("In addSnapshotRemove");
-        snapshotRemove(tracker.new SnapshotJob());
+        snapshotRemove(tracker.new SnapshotJob(), false);
     }
 
     @Test
@@ -132,7 +132,7 @@ public class BlobIdTrackerTest {
         LOG.info("In snapshotIgnoreAfterRemove");
         BlobIdTracker.SnapshotJob job = tracker.new SnapshotJob();
 
-        snapshotRemove(job);
+        snapshotRemove(job, false);
 
         // Since already retrieved the datastore should be empty unless the 
snapshot has actually run
         ScheduledFuture<?> scheduledFuture =
@@ -149,7 +149,8 @@ public class BlobIdTrackerTest {
         Clock clock = Clock.ACCURATE;
         BlobIdTracker.SnapshotJob job = tracker.new SnapshotJob(100, clock);
 
-        Set<String> present = snapshotRemove(job);
+        // Mimics a call to get after add and before remove similar to the 
calls in GC
+        Set<String> present = snapshotRemove(job, false);
 
         clock.waitUntil(System.currentTimeMillis() + 100);
 
@@ -162,12 +163,36 @@ public class BlobIdTrackerTest {
             read(dataStore.getAllMetadataRecords(BLOBREFERENCES.getType())));
     }
 
-    private Set<String> snapshotRemove(BlobIdTracker.SnapshotJob job) throws 
Exception {
+    @Test
+    public void snapshotBeforeRemove() throws Exception {
+        LOG.info("In snapshotBeforeRemove");
+
+        Clock clock = Clock.ACCURATE;
+        BlobIdTracker.SnapshotJob job = tracker.new SnapshotJob(100, clock);
+
+        //Mimic an intervening snapshot between add and remove by skipping the 
retrieve call.
+        Set<String> present = snapshotRemove(job, true);
+
+        clock.waitUntil(System.currentTimeMillis() + 100);
+
+        // Since already retrieved the datastore should not be empty unless 
the snapshot is ignored
+        ScheduledFuture<?> scheduledFuture =
+            scheduler.schedule(job, 0, TimeUnit.MILLISECONDS);
+        scheduledFuture.get();
+
+        assertEquals("Elements not equal after snapshot after remove", present,
+            read(dataStore.getAllMetadataRecords(BLOBREFERENCES.getType())));
+    }
+
+    private Set<String> snapshotRemove(BlobIdTracker.SnapshotJob job, boolean 
skipGetBeforeRemove) throws Exception {
         Set<String> initAdd = add(tracker, range(0, 4));
         ScheduledFuture<?> scheduledFuture =
             scheduler.schedule(job, 0, TimeUnit.MILLISECONDS);
         scheduledFuture.get();
-        assertEquals("Extra elements after add", initAdd, retrieve(tracker));
+
+        if (!skipGetBeforeRemove) {
+            assertEquals("Extra elements after add", initAdd, 
retrieve(tracker));
+        }
 
         remove(tracker, folder.newFile(), initAdd, range(1, 2));
         assertEquals("Extra elements after removes synced with datastore",


Reply via email to