Merge pull request #481 from mkevac/backupable

Allow creating and restoring backups from C
main
Igor Canadi 10 years ago
commit ee4aa9a0ee
  1. 98
      db/c.cc
  2. 42
      db/c_test.c
  3. 22
      examples/c_simple_example.c
  4. 53
      include/rocksdb/c.h

@ -29,6 +29,7 @@
#include "rocksdb/statistics.h" #include "rocksdb/statistics.h"
#include "rocksdb/slice_transform.h" #include "rocksdb/slice_transform.h"
#include "rocksdb/table.h" #include "rocksdb/table.h"
#include "rocksdb/utilities/backupable_db.h"
using rocksdb::Cache; using rocksdb::Cache;
using rocksdb::ColumnFamilyDescriptor; using rocksdb::ColumnFamilyDescriptor;
@ -69,12 +70,19 @@ using rocksdb::WritableFile;
using rocksdb::WriteBatch; using rocksdb::WriteBatch;
using rocksdb::WriteOptions; using rocksdb::WriteOptions;
using rocksdb::LiveFileMetaData; using rocksdb::LiveFileMetaData;
using rocksdb::BackupEngine;
using rocksdb::BackupableDBOptions;
using rocksdb::BackupInfo;
using rocksdb::RestoreOptions;
using std::shared_ptr; using std::shared_ptr;
extern "C" { extern "C" {
struct rocksdb_t { DB* rep; }; struct rocksdb_t { DB* rep; };
struct rocksdb_backup_engine_t { BackupEngine* rep; };
struct rocksdb_backup_engine_info_t { std::vector<BackupInfo> rep; };
struct rocksdb_restore_options_t { RestoreOptions rep; };
struct rocksdb_iterator_t { Iterator* rep; }; struct rocksdb_iterator_t { Iterator* rep; };
struct rocksdb_writebatch_t { WriteBatch rep; }; struct rocksdb_writebatch_t { WriteBatch rep; };
struct rocksdb_snapshot_t { const Snapshot* rep; }; struct rocksdb_snapshot_t { const Snapshot* rep; };
@ -527,6 +535,96 @@ rocksdb_t* rocksdb_open_for_read_only(
return result; return result;
} }
rocksdb_backup_engine_t* rocksdb_backup_engine_open(
const rocksdb_options_t* options,
const char* path,
char** errptr) {
BackupEngine* be;
if (SaveError(errptr, BackupEngine::Open(options->rep.env, BackupableDBOptions(path), &be))) {
return nullptr;
}
rocksdb_backup_engine_t* result = new rocksdb_backup_engine_t;
result->rep = be;
return result;
}
void rocksdb_backup_engine_create_new_backup(
rocksdb_backup_engine_t *be,
rocksdb_t *db,
char** errptr) {
SaveError(errptr, be->rep->CreateNewBackup(db->rep));
}
rocksdb_restore_options_t* rocksdb_restore_options_create() {
return new rocksdb_restore_options_t;
}
void rocksdb_restore_options_destroy(rocksdb_restore_options_t* opt) {
delete opt;
}
void rocksdb_restore_options_set_keep_log_files(
rocksdb_restore_options_t* opt, int v) {
opt->rep.keep_log_files = v;
}
void rocksdb_backup_engine_restore_db_from_latest_backup(
rocksdb_backup_engine_t *be,
const char* db_dir,
const char* wal_dir,
const rocksdb_restore_options_t *restore_options,
char** errptr) {
SaveError(errptr, be->rep->RestoreDBFromLatestBackup(std::string(db_dir), std::string(wal_dir), restore_options->rep));
}
const rocksdb_backup_engine_info_t* rocksdb_backup_engine_get_backup_info(
rocksdb_backup_engine_t* be) {
rocksdb_backup_engine_info_t* result = new rocksdb_backup_engine_info_t;
be->rep->GetBackupInfo(&result->rep);
return result;
}
int rocksdb_backup_engine_info_count(
const rocksdb_backup_engine_info_t* info) {
return static_cast<int>(info->rep.size());
}
const int64_t rocksdb_backup_engine_info_timestamp(
const rocksdb_backup_engine_info_t* info,
int index) {
return info->rep[index].timestamp;
}
const uint32_t rocksdb_backup_engine_info_backup_id(
const rocksdb_backup_engine_info_t* info,
int index) {
return info->rep[index].backup_id;
}
const uint64_t rocksdb_backup_engine_info_size(
const rocksdb_backup_engine_info_t* info,
int index) {
return info->rep[index].size;
}
const uint32_t rocksdb_backup_engine_info_number_files(
const rocksdb_backup_engine_info_t* info,
int index) {
return info->rep[index].number_files;
}
void rocksdb_backup_engine_info_destroy(
const rocksdb_backup_engine_info_t* info) {
delete info;
}
void rocksdb_backup_engine_close(
rocksdb_backup_engine_t *be) {
delete be->rep;
delete be;
}
void rocksdb_close(rocksdb_t* db) { void rocksdb_close(rocksdb_t* db) {
delete db->rep; delete db->rep;
delete db; delete db;

@ -10,9 +10,11 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <inttypes.h>
const char* phase = ""; const char* phase = "";
static char dbname[200]; static char dbname[200];
static char dbbackupname[200];
static void StartPhase(const char* name) { static void StartPhase(const char* name) {
fprintf(stderr, "=== Test %s\n", name); fprintf(stderr, "=== Test %s\n", name);
@ -346,6 +348,11 @@ int main(int argc, char** argv) {
GetTempDir(), GetTempDir(),
((int) geteuid())); ((int) geteuid()));
snprintf(dbbackupname, sizeof(dbbackupname),
"%s/rocksdb_c_test-%d-backup",
GetTempDir(),
((int) geteuid()));
StartPhase("create_objects"); StartPhase("create_objects");
cmp = rocksdb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName); cmp = rocksdb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);
env = rocksdb_create_default_env(); env = rocksdb_create_default_env();
@ -396,6 +403,41 @@ int main(int argc, char** argv) {
CheckNoError(err); CheckNoError(err);
CheckGet(db, roptions, "foo", "hello"); CheckGet(db, roptions, "foo", "hello");
StartPhase("backup_and_restore");
{
rocksdb_destroy_db(options, dbbackupname, &err);
CheckNoError(err);
rocksdb_backup_engine_t *be = rocksdb_backup_engine_open(options, dbbackupname, &err);
CheckNoError(err);
rocksdb_backup_engine_create_new_backup(be, db, &err);
CheckNoError(err);
rocksdb_delete(db, woptions, "foo", 3, &err);
CheckNoError(err);
rocksdb_close(db);
rocksdb_destroy_db(options, dbname, &err);
CheckNoError(err);
rocksdb_restore_options_t *restore_options = rocksdb_restore_options_create();
rocksdb_restore_options_set_keep_log_files(restore_options, 0);
rocksdb_backup_engine_restore_db_from_latest_backup(be, dbname, dbname, restore_options, &err);
CheckNoError(err);
rocksdb_restore_options_destroy(restore_options);
rocksdb_options_set_error_if_exists(options, 0);
db = rocksdb_open(options, dbname, &err);
CheckNoError(err);
rocksdb_options_set_error_if_exists(options, 1);
CheckGet(db, roptions, "foo", "hello");
rocksdb_backup_engine_close(be);
}
StartPhase("compactall"); StartPhase("compactall");
rocksdb_compact_range(db, NULL, 0, NULL, 0); rocksdb_compact_range(db, NULL, 0, NULL, 0);
CheckGet(db, roptions, "foo", "hello"); CheckGet(db, roptions, "foo", "hello");

@ -8,9 +8,11 @@
#include <unistd.h> // sysconf() - get CPU count #include <unistd.h> // sysconf() - get CPU count
const char DBPath[] = "/tmp/rocksdb_simple_example"; const char DBPath[] = "/tmp/rocksdb_simple_example";
const char DBBackupPath[] = "/tmp/rocksdb_simple_example_backup";
int main(int argc, char **argv) { int main(int argc, char **argv) {
rocksdb_t *db; rocksdb_t *db;
rocksdb_backup_engine_t *be;
rocksdb_options_t *options = rocksdb_options_create(); rocksdb_options_t *options = rocksdb_options_create();
// Optimize RocksDB. This is the easiest way to // Optimize RocksDB. This is the easiest way to
// get RocksDB to perform well // get RocksDB to perform well
@ -25,6 +27,10 @@ int main(int argc, char **argv) {
db = rocksdb_open(options, DBPath, &err); db = rocksdb_open(options, DBPath, &err);
assert(!err); assert(!err);
// open Backup Engine that we will use for backing up or database
be = rocksdb_backup_engine_open(options, DBBackupPath, &err);
assert(!err);
// Put key-value // Put key-value
rocksdb_writeoptions_t *writeoptions = rocksdb_writeoptions_create(); rocksdb_writeoptions_t *writeoptions = rocksdb_writeoptions_create();
const char key[] = "key"; const char key[] = "key";
@ -41,10 +47,26 @@ int main(int argc, char **argv) {
assert(strcmp(returned_value, "value") == 0); assert(strcmp(returned_value, "value") == 0);
free(returned_value); free(returned_value);
// create new backup in a directory specified by DBBackupPath
rocksdb_backup_engine_create_new_backup(be, db, &err);
assert(!err);
rocksdb_close(db);
// If something is wrong, you might want to restore data from last backup
rocksdb_restore_options_t *restore_options = rocksdb_restore_options_create();
rocksdb_backup_engine_restore_db_from_latest_backup(be, DBPath, DBPath, restore_options, &err);
assert(!err);
rocksdb_restore_options_destroy(restore_options);
db = rocksdb_open(options, DBPath, &err);
assert(!err);
// cleanup // cleanup
rocksdb_writeoptions_destroy(writeoptions); rocksdb_writeoptions_destroy(writeoptions);
rocksdb_readoptions_destroy(readoptions); rocksdb_readoptions_destroy(readoptions);
rocksdb_options_destroy(options); rocksdb_options_destroy(options);
rocksdb_backup_engine_close(be);
rocksdb_close(db); rocksdb_close(db);
return 0; return 0;

@ -55,6 +55,9 @@ extern "C" {
/* Exported types */ /* Exported types */
typedef struct rocksdb_t rocksdb_t; typedef struct rocksdb_t rocksdb_t;
typedef struct rocksdb_backup_engine_t rocksdb_backup_engine_t;
typedef struct rocksdb_backup_engine_info_t rocksdb_backup_engine_info_t;
typedef struct rocksdb_restore_options_t rocksdb_restore_options_t;
typedef struct rocksdb_cache_t rocksdb_cache_t; typedef struct rocksdb_cache_t rocksdb_cache_t;
typedef struct rocksdb_compactionfilter_t rocksdb_compactionfilter_t; typedef struct rocksdb_compactionfilter_t rocksdb_compactionfilter_t;
typedef struct rocksdb_compactionfiltercontext_t typedef struct rocksdb_compactionfiltercontext_t
@ -104,6 +107,56 @@ extern rocksdb_t* rocksdb_open_for_read_only(
unsigned char error_if_log_file_exist, unsigned char error_if_log_file_exist,
char** errptr); char** errptr);
extern rocksdb_backup_engine_t* rocksdb_backup_engine_open(
const rocksdb_options_t* options,
const char* path,
char** errptr);
extern void rocksdb_backup_engine_create_new_backup(
rocksdb_backup_engine_t* be,
rocksdb_t* db,
char** errptr);
extern rocksdb_restore_options_t* rocksdb_restore_options_create();
extern void rocksdb_restore_options_destroy(rocksdb_restore_options_t* opt);
extern void rocksdb_restore_options_set_keep_log_files(
rocksdb_restore_options_t* opt, int v);
extern void rocksdb_backup_engine_restore_db_from_latest_backup(
rocksdb_backup_engine_t *be,
const char* db_dir,
const char* wal_dir,
const rocksdb_restore_options_t *restore_options,
char** errptr);
extern const rocksdb_backup_engine_info_t* rocksdb_backup_engine_get_backup_info(
rocksdb_backup_engine_t* be);
extern int rocksdb_backup_engine_info_count(
const rocksdb_backup_engine_info_t* info);
extern const int64_t rocksdb_backup_engine_info_timestamp(
const rocksdb_backup_engine_info_t* info,
int index);
extern const uint32_t rocksdb_backup_engine_info_backup_id(
const rocksdb_backup_engine_info_t* info,
int index);
extern const uint64_t rocksdb_backup_engine_info_size(
const rocksdb_backup_engine_info_t* info,
int index);
extern const uint32_t rocksdb_backup_engine_info_number_files(
const rocksdb_backup_engine_info_t* info,
int index);
extern void rocksdb_backup_engine_info_destroy(
const rocksdb_backup_engine_info_t *info);
extern void rocksdb_backup_engine_close(
rocksdb_backup_engine_t* be);
extern rocksdb_t* rocksdb_open_column_families( extern rocksdb_t* rocksdb_open_column_families(
const rocksdb_options_t* options, const rocksdb_options_t* options,
const char* name, const char* name,

Loading…
Cancel
Save