Author: frm
Date: Fri Apr 7 07:41:21 2017
New Revision: 1790514
URL: http://svn.apache.org/viewvc?rev=1790514&view=rev
Log:
OAK-6046 - Make initial references for cleanup consistent with cleaned up TARs
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1790514&r1=1790513&r2=1790514&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
Fri Apr 7 07:41:21 2017
@@ -155,6 +155,21 @@ public class FileStore extends AbstractF
@Nonnull
private final SegmentNotFoundExceptionListener snfeListener;
+ private final Supplier<Set<UUID>> referencesSupplier = new
Supplier<Set<UUID>>() {
+
+ @Override
+ public Set<UUID> get() {
+ Set<UUID> references = newHashSet();
+ for (SegmentId id : tracker.getReferencedSegmentIds()) {
+ if (id.isBulkSegmentId()) {
+ references.add(id.asUUID());
+ }
+ }
+ return references;
+ }
+
+ };
+
FileStore(final FileStoreBuilder builder) throws
InvalidFileStoreVersionException, IOException {
super(builder);
@@ -810,13 +825,7 @@ public class FileStore extends AbstractF
// to clear stale weak references in the SegmentTracker
System.gc();
- Set<UUID> bulkRefs = newHashSet();
- for (SegmentId id : tracker.getReferencedSegmentIds()) {
- if (id.isBulkSegmentId()) {
- bulkRefs.add(id.asUUID());
- }
- }
- CleanupResult cleanupResult = tarFiles.cleanup(bulkRefs,
compactionResult.reclaimer());
+ CleanupResult cleanupResult = tarFiles.cleanup(referencesSupplier,
compactionResult.reclaimer());
if (cleanupResult.isInterrupted()) {
gcListener.info("TarMK GC #{}: cleanup interrupted", GC_COUNT);
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java?rev=1790514&r1=1790513&r2=1790514&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
Fri Apr 7 07:41:21 2017
@@ -45,6 +45,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
import com.google.common.io.Closer;
import org.apache.jackrabbit.oak.plugins.blob.ReferenceCollector;
import org.apache.jackrabbit.oak.segment.SegmentGraph.SegmentGraphVisitor;
@@ -404,7 +405,7 @@ class TarFiles implements Closeable {
writer = newWriter;
}
- CleanupResult cleanup(Set<UUID> references, Predicate<Integer>
reclaimGeneration) throws IOException {
+ CleanupResult cleanup(Supplier<Set<UUID>> referencesSupplier,
Predicate<Integer> reclaimGeneration) throws IOException {
checkReadWrite();
CleanupResult result = new CleanupResult();
@@ -437,6 +438,13 @@ class TarFiles implements Closeable {
cleaned.put(reader, reader);
result.reclaimedSize += reader.size();
}
+
+ // The set of references has to be computed while holding the lock.
+ // This prevents a time-of-check to time-of-use race condition. See
+ // OAK-6046 for further details.
+
+ Set<UUID> references = referencesSupplier.get();
+
Set<UUID> reclaim = newHashSet();
for (TarReader reader : cleaned.keySet()) {
if (shutdown) {