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 ju...@apache.org on 2013/12/04 14:31:41 UTC
svn commit: r1547796 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackup.java
test/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupTest.java
Author: jukka
Date: Wed Dec 4 13:31:41 2013
New Revision: 1547796
URL: http://svn.apache.org/r1547796
Log:
OAK-1159: Backup and restore
Add a test for the super-root comparison case
Fix the comparison to always use the root (and not super-root) state
Address the todo for optimizing the incremental backup
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackup.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackup.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackup.java?rev=1547796&r1=1547795&r2=1547796&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackup.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackup.java Wed Dec 4 13:31:41 2013
@@ -39,7 +39,7 @@ public class FileStoreBackup {
private static final long DEFAULT_LIFETIME = TimeUnit.HOURS.toMillis(1);
- static int CACHE_SIZE = 256;
+ static int MAX_FILE_SIZE = 256;
public static void backup(NodeStore store, File destination)
throws IOException {
@@ -49,32 +49,44 @@ public class FileStoreBackup {
String checkpoint = store.checkpoint(DEFAULT_LIFETIME);
NodeState current = store.retrieve(checkpoint);
if (current == null) {
- log.debug("Unable to retrieve checkpoint {}", checkpoint);
- return;
+ // unable to retrieve the checkpoint; use root state instead
+ current = store.getRoot();
}
// 2. init filestore
- destination.mkdirs();
- FileStore backup = null;
+ FileStore backup = new FileStore(destination, MAX_FILE_SIZE, false);
try {
- backup = new FileStore(destination, current, CACHE_SIZE,
- CACHE_SIZE, false);
+ Journal journal = backup.getJournal("root");
- // TODO optimize incremental backup
- Journal root = backup.getJournal("root");
- SegmentNodeState state = new SegmentNodeState(backup.getWriter()
- .getDummySegment(), root.getHead());
+ SegmentNodeState state = new SegmentNodeState(
+ backup.getWriter().getDummySegment(), journal.getHead());
SegmentNodeBuilder builder = state.builder();
- current.compareAgainstBaseState(state,
- new ApplyDiff(builder.child("root")));
- root.setHead(state.getRecordId(), builder.getNodeState()
- .getRecordId());
- } finally {
- if (backup != null) {
- backup.close();
+ String beforeCheckpoint = state.getString("checkpoint");
+ if (beforeCheckpoint == null) {
+ // 3.1 no stored checkpoint, so do the initial full backup
+ builder.setChildNode("root", current);
+ } else {
+ // 3.2 try to retrieve the previously backed up checkpoint
+ NodeState before = store.retrieve(beforeCheckpoint);
+ if (before != null) {
+ // the previous checkpoint is no longer available,
+ // so use the backed up state as the basis of the
+ // incremental backup diff
+ before = state.getChildNode("root");
+ }
+ current.compareAgainstBaseState(
+ before, new ApplyDiff(builder.child("root")));
}
- log.debug("Backup done in {} ms.", System.currentTimeMillis() - s);
+ builder.setProperty("checkpoint", checkpoint);
+
+ // 4. commit the backup
+ journal.setHead(
+ state.getRecordId(), builder.getNodeState().getRecordId());
+ } finally {
+ backup.close();
}
+
+ log.debug("Backup done in {} ms.", System.currentTimeMillis() - s);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupTest.java?rev=1547796&r1=1547795&r2=1547796&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupTest.java Wed Dec 4 13:31:41 2013
@@ -19,7 +19,6 @@
package org.apache.jackrabbit.oak.plugins.backup;
import static org.apache.commons.io.FileUtils.deleteQuietly;
-import static org.apache.jackrabbit.oak.plugins.backup.FileStoreBackup.CACHE_SIZE;
import static org.junit.Assert.assertEquals;
import java.io.File;
@@ -59,7 +58,9 @@ public class FileStoreBackupTest {
@Test
public void testBackup() throws Exception {
- NodeStore store = newSegmentNodeStore(src);
+ FileStore source = new FileStore(src, 256, false);
+
+ NodeStore store = new SegmentNodeStore(source);
init(store);
// initial content
@@ -70,19 +71,23 @@ public class FileStoreBackupTest {
addTestContent(store);
FileStoreBackup.backup(store, destination);
compare(store, destination);
+
+ source.close();
}
private static void addTestContent(NodeStore store)
throws CommitFailedException {
NodeBuilder builder = store.getRoot().builder();
builder.child("test-backup");
+ builder.child("root"); // make sure we don't backup the super-root
store.merge(builder, EmptyHook.INSTANCE, null);
}
private static void compare(NodeStore store, File destination)
throws IOException {
- NodeStore backup = newSegmentNodeStore(destination);
- assertEquals(store.getRoot(), backup.getRoot());
+ FileStore backup = new FileStore(destination, 256, false);
+ assertEquals(store.getRoot(), new SegmentNodeStore(backup).getRoot());
+ backup.close();
}
private static void init(NodeStore store) {
@@ -90,9 +95,4 @@ public class FileStoreBackupTest {
.with(new InitialContent()).createContentRepository();
}
- private static SegmentNodeStore newSegmentNodeStore(File file)
- throws IOException {
- return new SegmentNodeStore(new FileStore(file, CACHE_SIZE, CACHE_SIZE,
- true));
- }
}