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 al...@apache.org on 2016/11/23 15:57:52 UTC
svn commit: r1770994 - in /jackrabbit/oak/trunk/oak-segment-tar/src:
main/java/org/apache/jackrabbit/oak/segment/file/
test/java/org/apache/jackrabbit/oak/segment/file/
Author: alexparvulescu
Date: Wed Nov 23 15:57:52 2016
New Revision: 1770994
URL: http://svn.apache.org/viewvc?rev=1770994&view=rev
Log:
OAK-5116 GCJournal should persist size only when compaction is successful
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/GCJournal.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.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=1770994&r1=1770993&r2=1770994&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 Wed Nov 23 15:57:52 2016
@@ -1117,7 +1117,7 @@ public class FileStore extends AbstractF
long finalSize = size();
long reclaimedSize = initialSize - afterCleanupSize;
stats.reclaimed(reclaimedSize);
- gcJournal.persist(reclaimedSize, finalSize);
+ gcJournal.persist(reclaimedSize, finalSize, getGcGeneration());
gcListener.cleaned(reclaimedSize, finalSize);
gcListener.info("TarMK GC #{}: cleanup completed in {} ({} ms). Post cleanup size is {} ({} bytes)" +
" and space reclaimed {} ({} bytes).",
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java?rev=1770994&r1=1770993&r2=1770994&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/GCJournal.java Wed Nov 23 15:57:52 2016
@@ -41,8 +41,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Persists the repository size and the reclaimed size following a cleanup operation in the
- * {@link #GC_JOURNAL gc journal} file with the format: 'repoSize, reclaimedSize, timestamp'.
+ * Persists the repository size and the reclaimed size following a cleanup
+ * operation in the {@link #GC_JOURNAL gc journal} file with the format:
+ * 'repoSize, reclaimedSize, timestamp, gcGen'.
*/
public class GCJournal {
@@ -59,8 +60,20 @@ public class GCJournal {
this.directory = checkNotNull(directory);
}
- public synchronized void persist(long reclaimedSize, long repoSize) {
- latest = new GCJournalEntry(repoSize, reclaimedSize, System.currentTimeMillis());
+ /**
+ * Persists the repository size and the reclaimed size following a cleanup
+ * operation
+ */
+ public synchronized void persist(long reclaimedSize, long repoSize,
+ int gcGeneration) {
+ GCJournalEntry current = read();
+ if (current.getGcGeneration() == gcGeneration) {
+ // failed compaction, only update the journal if the generation
+ // increases
+ return;
+ }
+ latest = new GCJournalEntry(repoSize, reclaimedSize,
+ System.currentTimeMillis(), gcGeneration);
Path path = new File(directory, GC_JOURNAL).toPath();
try {
try (BufferedWriter w = newBufferedWriter(path, UTF_8, WRITE,
@@ -73,6 +86,9 @@ public class GCJournal {
}
}
+ /**
+ * Returns the latest entry available
+ */
public synchronized GCJournalEntry read() {
if (latest == null) {
List<String> all = readLines();
@@ -86,6 +102,9 @@ public class GCJournal {
return latest;
}
+ /**
+ * Returns all available entries from the journal
+ */
public synchronized Collection<GCJournalEntry> readAll() {
List<GCJournalEntry> all = new ArrayList<GCJournalEntry>();
for (String l : readLines()) {
@@ -108,30 +127,38 @@ public class GCJournal {
static class GCJournalEntry {
- static GCJournalEntry EMPTY = new GCJournalEntry(-1, -1, -1);
+ static GCJournalEntry EMPTY = new GCJournalEntry(-1, -1, -1, -1);
private final long repoSize;
private final long reclaimedSize;
private final long ts;
+ private final int gcGeneration;
- public GCJournalEntry(long repoSize, long reclaimedSize, long ts) {
+ public GCJournalEntry(long repoSize, long reclaimedSize, long ts,
+ int gcGeneration) {
this.repoSize = repoSize;
this.reclaimedSize = reclaimedSize;
this.ts = ts;
+ this.gcGeneration = gcGeneration;
}
@Override
public String toString() {
- return repoSize + "," + reclaimedSize + "," + ts;
+ return repoSize + "," + reclaimedSize + "," + ts + ","
+ + gcGeneration;
}
static GCJournalEntry fromString(String in) {
String[] items = in.split(",");
- if (items.length == 3) {
+ if (items.length == 3 || items.length == 4) {
long repoSize = safeParse(items[0]);
long reclaimedSize = safeParse(items[1]);
long ts = safeParse(items[2]);
- return new GCJournalEntry(repoSize, reclaimedSize, ts);
+ int gcGen = -1;
+ if (items.length == 4) {
+ gcGen = (int) safeParse(items[3]);
+ }
+ return new GCJournalEntry(repoSize, reclaimedSize, ts, gcGen);
}
return GCJournalEntry.EMPTY;
}
@@ -157,11 +184,17 @@ public class GCJournal {
return ts;
}
+ public int getGcGeneration() {
+ return gcGeneration;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + (int) (reclaimedSize ^ (reclaimedSize >>> 32));
+ result = prime * result + gcGeneration;
+ result = prime * result
+ + (int) (reclaimedSize ^ (reclaimedSize >>> 32));
result = prime * result + (int) (repoSize ^ (repoSize >>> 32));
result = prime * result + (int) (ts ^ (ts >>> 32));
return result;
@@ -176,6 +209,8 @@ public class GCJournal {
if (getClass() != obj.getClass())
return false;
GCJournalEntry other = (GCJournalEntry) obj;
+ if (gcGeneration != other.gcGeneration)
+ return false;
if (reclaimedSize != other.reclaimedSize)
return false;
if (repoSize != other.repoSize)
@@ -184,5 +219,6 @@ public class GCJournal {
return false;
return true;
}
+
}
}
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java?rev=1770994&r1=1770993&r2=1770994&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/GcJournalTest.java Wed Nov 23 15:57:52 2016
@@ -44,21 +44,27 @@ public class GcJournalTest {
File directory = segmentFolder.newFolder();
GCJournal gc = new GCJournal(directory);
- gc.persist(0, 100);
+ gc.persist(0, 100, 1);
GCJournalEntry e0 = gc.read();
assertEquals(100, e0.getRepoSize());
assertEquals(0, e0.getReclaimedSize());
- gc.persist(0, 250);
+ gc.persist(0, 250, 2);
GCJournalEntry e1 = gc.read();
assertEquals(250, e1.getRepoSize());
assertEquals(0, e1.getReclaimedSize());
-
- gc.persist(50, 200);
+
+ gc.persist(50, 200, 3);
GCJournalEntry e2 = gc.read();
assertEquals(200, e2.getRepoSize());
assertEquals(50, e2.getReclaimedSize());
+ // same gen
+ gc.persist(75, 300, 3);
+ GCJournalEntry e3 = gc.read();
+ assertEquals(200, e3.getRepoSize());
+ assertEquals(50, e3.getReclaimedSize());
+
Collection<GCJournalEntry> all = gc.readAll();
assertEquals(all.size(), 3);