mirror of https://github.com/facebook/rocksdb.git
Merge pull request #398 from fyrz/RocksJava-CreateCheckPoint
[RocksJava] Support for stored snapshots
This commit is contained in:
commit
b8136a7d27
|
@ -4,6 +4,7 @@ NATIVE_JAVA_CLASSES = org.rocksdb.AbstractComparator\
|
||||||
org.rocksdb.BackupableDBOptions\
|
org.rocksdb.BackupableDBOptions\
|
||||||
org.rocksdb.BlockBasedTableConfig\
|
org.rocksdb.BlockBasedTableConfig\
|
||||||
org.rocksdb.BloomFilter\
|
org.rocksdb.BloomFilter\
|
||||||
|
org.rocksdb.Checkpoint\
|
||||||
org.rocksdb.ColumnFamilyHandle\
|
org.rocksdb.ColumnFamilyHandle\
|
||||||
org.rocksdb.ColumnFamilyOptions\
|
org.rocksdb.ColumnFamilyOptions\
|
||||||
org.rocksdb.Comparator\
|
org.rocksdb.Comparator\
|
||||||
|
@ -50,6 +51,7 @@ endif
|
||||||
JAVA_TESTS = org.rocksdb.test.BackupableDBOptionsTest\
|
JAVA_TESTS = org.rocksdb.test.BackupableDBOptionsTest\
|
||||||
org.rocksdb.test.BackupableDBTest\
|
org.rocksdb.test.BackupableDBTest\
|
||||||
org.rocksdb.test.BlockBasedTableConfigTest\
|
org.rocksdb.test.BlockBasedTableConfigTest\
|
||||||
|
org.rocksdb.test.CheckPointTest\
|
||||||
org.rocksdb.test.ColumnFamilyOptionsTest\
|
org.rocksdb.test.ColumnFamilyOptionsTest\
|
||||||
org.rocksdb.test.ColumnFamilyTest\
|
org.rocksdb.test.ColumnFamilyTest\
|
||||||
org.rocksdb.test.ComparatorOptionsTest\
|
org.rocksdb.test.ComparatorOptionsTest\
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
|
||||||
|
package org.rocksdb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides Checkpoint functionality. Checkpoints
|
||||||
|
* provide persistent snapshots of RocksDB databases.
|
||||||
|
*/
|
||||||
|
public class Checkpoint extends RocksObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Checkpoint object to be used for creating open-able
|
||||||
|
* snapshots.
|
||||||
|
*
|
||||||
|
* @param db {@link RocksDB} instance.
|
||||||
|
* @return a Checkpoint instance.
|
||||||
|
*
|
||||||
|
* @throws java.lang.IllegalArgumentException if {@link RocksDB}
|
||||||
|
* instance is null.
|
||||||
|
* @throws java.lang.IllegalStateException if {@link RocksDB}
|
||||||
|
* instance is not initialized.
|
||||||
|
*/
|
||||||
|
public static Checkpoint create(RocksDB db) {
|
||||||
|
if (db == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"RocksDB instance shall not be null.");
|
||||||
|
} else if (!db.isInitialized()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"RocksDB instance must be initialized.");
|
||||||
|
}
|
||||||
|
Checkpoint checkpoint = new Checkpoint(db);
|
||||||
|
return checkpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Builds an open-able snapshot of RocksDB on the same disk, which
|
||||||
|
* accepts an output directory on the same disk, and under the directory
|
||||||
|
* (1) hard-linked SST files pointing to existing live SST files
|
||||||
|
* (2) a copied manifest files and other files</p>
|
||||||
|
*
|
||||||
|
* @param checkpointPath path to the folder where the snapshot is going
|
||||||
|
* to be stored.
|
||||||
|
* @throws RocksDBException thrown if an error occurs within the native
|
||||||
|
* part of the library.
|
||||||
|
*/
|
||||||
|
public void createCheckpoint(String checkpointPath)
|
||||||
|
throws RocksDBException {
|
||||||
|
createCheckpoint(nativeHandle_, checkpointPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void disposeInternal() {
|
||||||
|
disposeInternal(nativeHandle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Checkpoint(RocksDB db) {
|
||||||
|
super();
|
||||||
|
nativeHandle_ = newCheckpoint(db.nativeHandle_);
|
||||||
|
db_ = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
RocksDB db_;
|
||||||
|
|
||||||
|
private static native long newCheckpoint(long dbHandle);
|
||||||
|
private native void disposeInternal(long handle);
|
||||||
|
|
||||||
|
private native void createCheckpoint(long handle, String checkpointPath)
|
||||||
|
throws RocksDBException;
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package org.rocksdb.test;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.rocksdb.Checkpoint;
|
||||||
|
import org.rocksdb.Options;
|
||||||
|
import org.rocksdb.RocksDB;
|
||||||
|
import org.rocksdb.RocksDBException;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class CheckPointTest {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static final RocksMemoryResource rocksMemoryResource =
|
||||||
|
new RocksMemoryResource();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder dbFolder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder checkpointFolder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkPoint() throws RocksDBException {
|
||||||
|
RocksDB db = null;
|
||||||
|
Options options = null;
|
||||||
|
Checkpoint checkpoint = null;
|
||||||
|
try {
|
||||||
|
options = new Options().
|
||||||
|
setCreateIfMissing(true);
|
||||||
|
db = RocksDB.open(options,
|
||||||
|
dbFolder.getRoot().getAbsolutePath());
|
||||||
|
db.put("key".getBytes(), "value".getBytes());
|
||||||
|
checkpoint = Checkpoint.create(db);
|
||||||
|
checkpoint.createCheckpoint(checkpointFolder.
|
||||||
|
getRoot().getAbsolutePath() + "/snapshot1");
|
||||||
|
db.put("key2".getBytes(), "value2".getBytes());
|
||||||
|
checkpoint.createCheckpoint(checkpointFolder.
|
||||||
|
getRoot().getAbsolutePath() + "/snapshot2");
|
||||||
|
db.close();
|
||||||
|
db = RocksDB.open(options,
|
||||||
|
checkpointFolder.getRoot().getAbsolutePath() +
|
||||||
|
"/snapshot1");
|
||||||
|
assertThat(new String(db.get("key".getBytes()))).
|
||||||
|
isEqualTo("value");
|
||||||
|
assertThat(db.get("key2".getBytes())).isNull();
|
||||||
|
db.close();
|
||||||
|
db = RocksDB.open(options,
|
||||||
|
checkpointFolder.getRoot().getAbsolutePath() +
|
||||||
|
"/snapshot2");
|
||||||
|
assertThat(new String(db.get("key".getBytes()))).
|
||||||
|
isEqualTo("value");
|
||||||
|
assertThat(new String(db.get("key2".getBytes()))).
|
||||||
|
isEqualTo("value2");
|
||||||
|
} finally {
|
||||||
|
if (db != null) {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
if (options != null) {
|
||||||
|
options.dispose();
|
||||||
|
}
|
||||||
|
if (checkpoint != null) {
|
||||||
|
checkpoint.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void failIfDbIsNull() {
|
||||||
|
Checkpoint.create(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void failIfDbNotInitialized() throws RocksDBException {
|
||||||
|
RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
|
||||||
|
db.dispose();
|
||||||
|
Checkpoint.create(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RocksDBException.class)
|
||||||
|
public void failWithIllegalPath() throws RocksDBException {
|
||||||
|
RocksDB db = null;
|
||||||
|
Checkpoint checkpoint = null;
|
||||||
|
try {
|
||||||
|
db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
|
||||||
|
checkpoint = Checkpoint.create(db);
|
||||||
|
checkpoint.createCheckpoint("/Z:///:\\C:\\TZ/-");
|
||||||
|
} finally {
|
||||||
|
if (db != null) {
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
if (checkpoint != null) {
|
||||||
|
checkpoint.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright (c) 2014, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under the BSD-style license found in the
|
||||||
|
// LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
// of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
//
|
||||||
|
// This file implements the "bridge" between Java and C++ and enables
|
||||||
|
// calling c++ rocksdb::Checkpoint methods from Java side.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <jni.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "include/org_rocksdb_Checkpoint.h"
|
||||||
|
#include "rocksjni/portal.h"
|
||||||
|
#include "rocksdb/db.h"
|
||||||
|
#include "rocksdb/utilities/checkpoint.h"
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Checkpoint
|
||||||
|
* Method: newCheckpoint
|
||||||
|
* Signature: (J)J
|
||||||
|
*/
|
||||||
|
jlong Java_org_rocksdb_Checkpoint_newCheckpoint(JNIEnv* env,
|
||||||
|
jclass jclazz, jlong jdb_handle) {
|
||||||
|
auto db = reinterpret_cast<rocksdb::DB*>(jdb_handle);
|
||||||
|
rocksdb::Checkpoint* checkpoint;
|
||||||
|
rocksdb::Checkpoint::Create(db, &checkpoint);
|
||||||
|
return reinterpret_cast<jlong>(checkpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Checkpoint
|
||||||
|
* Method: dispose
|
||||||
|
* Signature: (J)V
|
||||||
|
*/
|
||||||
|
void Java_org_rocksdb_Checkpoint_disposeInternal(JNIEnv* env, jobject jobj,
|
||||||
|
jlong jhandle) {
|
||||||
|
auto checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(jhandle);
|
||||||
|
assert(checkpoint);
|
||||||
|
delete checkpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_rocksdb_Checkpoint
|
||||||
|
* Method: createCheckpoint
|
||||||
|
* Signature: (JLjava/lang/String;)V
|
||||||
|
*/
|
||||||
|
void Java_org_rocksdb_Checkpoint_createCheckpoint(
|
||||||
|
JNIEnv* env, jobject jobj, jlong jcheckpoint_handle,
|
||||||
|
jstring jcheckpoint_path) {
|
||||||
|
auto checkpoint = reinterpret_cast<rocksdb::Checkpoint*>(
|
||||||
|
jcheckpoint_handle);
|
||||||
|
const char* checkpoint_path = env->GetStringUTFChars(
|
||||||
|
jcheckpoint_path, 0);
|
||||||
|
rocksdb::Status s = checkpoint->CreateCheckpoint(
|
||||||
|
checkpoint_path);
|
||||||
|
env->ReleaseStringUTFChars(jcheckpoint_path, checkpoint_path);
|
||||||
|
if (!s.ok()) {
|
||||||
|
rocksdb::RocksDBExceptionJni::ThrowNew(env, s);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue