Skip to content

Commit 49978f7

Browse files
committed
add the possibility to do live backups
See http://rocksdb.org/blog/2609/use-checkpoints-for-efficient-snapshots/ for more infos
1 parent 7561b0e commit 49978f7

File tree

4 files changed

+105
-5
lines changed

4 files changed

+105
-5
lines changed

c_src/erocksdb.cc

+48-5
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static ErlNifFunc nif_funcs[] =
7474

7575
{"async_snapshot", 2, erocksdb::async_snapshot},
7676
{"async_release_snapshot", 2, erocksdb::async_release_snapshot},
77-
77+
{"async_checkpoint", 3, erocksdb::async_checkpoint},
7878

7979
{"async_iterator", 3, erocksdb::async_iterator},
8080
{"async_iterator", 4, erocksdb::async_iterator},
@@ -1112,11 +1112,8 @@ async_iterator(
11121112

11131113
// Parse out the read options
11141114
rocksdb::ReadOptions *opts = new rocksdb::ReadOptions;
1115-
1116-
if(NULL!=snapshot)
1117-
opts->snapshot = snapshot;
1118-
11191115
fold(env, options_ref, parse_read_option, *opts);
1116+
opts->snapshot = snapshot;
11201117

11211118
erocksdb::WorkTask *work_item = new erocksdb::IterTask(env, caller_ref,
11221119
db_ptr.get(), keys_only, opts,
@@ -1289,6 +1286,52 @@ async_iterator_move(
12891286
} // async_iter_move
12901287

12911288

1289+
ERL_NIF_TERM
1290+
async_checkpoint(
1291+
ErlNifEnv* env,
1292+
int argc,
1293+
const ERL_NIF_TERM argv[])
1294+
{
1295+
const ERL_NIF_TERM& caller_ref = argv[0];
1296+
const ERL_NIF_TERM& handle_ref = argv[1];
1297+
1298+
char path[4096];
1299+
1300+
1301+
ReferencePtr<DbObject> db_ptr;
1302+
1303+
db_ptr.assign(DbObject::RetrieveDbObject(env, handle_ref));
1304+
1305+
if(NULL==db_ptr.get())
1306+
{
1307+
return enif_make_badarg(env);
1308+
}
1309+
1310+
// is this even possible?
1311+
if(NULL == db_ptr->m_Db)
1312+
return send_reply(env, caller_ref, error_einval(env));
1313+
1314+
if(!enif_get_string(env, argv[2], path, sizeof(path), ERL_NIF_LATIN1))
1315+
{
1316+
return enif_make_badarg(env);
1317+
}
1318+
1319+
erocksdb_priv_data& priv = *static_cast<erocksdb_priv_data *>(enif_priv_data(env));
1320+
1321+
erocksdb::WorkTask *work_item = new erocksdb::CheckpointTask(env, caller_ref, db_ptr.get(), path);
1322+
1323+
if(false == priv.thread_pool.submit(work_item))
1324+
{
1325+
delete work_item;
1326+
return send_reply(env, caller_ref,
1327+
enif_make_tuple2(env, erocksdb::ATOM_ERROR, caller_ref));
1328+
}
1329+
1330+
return erocksdb::ATOM_OK;
1331+
1332+
} // async_checkpoint
1333+
1334+
12921335
} // namespace erocksdb
12931336

12941337

c_src/erocksdb.h

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ ERL_NIF_TERM erocksdb_status(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
3939
ERL_NIF_TERM erocksdb_destroy(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
4040
ERL_NIF_TERM erocksdb_repair(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
4141
ERL_NIF_TERM erocksdb_is_empty(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
42+
ERL_NIF_TERM erocksdb_checkpoint(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
4243
}
4344

4445
namespace erocksdb {
@@ -48,6 +49,7 @@ ERL_NIF_TERM async_snapshot(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
4849
ERL_NIF_TERM async_release_snapshot(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
4950
ERL_NIF_TERM async_write(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
5051
ERL_NIF_TERM async_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
52+
ERL_NIF_TERM async_checkpoint(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
5153

5254
ERL_NIF_TERM async_iterator(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
5355
ERL_NIF_TERM async_iterator_move(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);

c_src/workitems.h

+44
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "rocksdb/db.h"
2929
#include "rocksdb/write_batch.h"
30+
#include "rocksdb/utilities/checkpoint.h"
3031

3132

3233
#ifndef INCL_MUTEX_H
@@ -197,6 +198,49 @@ class ReleaseSnapshotTask : public WorkTask
197198
}; // class GetSnapshotTask
198199

199200

201+
/**
202+
* Background object for async snapshot creation
203+
*/
204+
205+
class CheckpointTask : public WorkTask
206+
{
207+
protected:
208+
std::string path;
209+
210+
public:
211+
CheckpointTask(ErlNifEnv *_caller_env,
212+
ERL_NIF_TERM _caller_ref,
213+
DbObject *_db_handle,
214+
const std::string& path_)
215+
: WorkTask(_caller_env, _caller_ref, _db_handle),
216+
path(path_)
217+
{
218+
219+
};
220+
221+
virtual ~CheckpointTask() {};
222+
223+
virtual work_result operator()()
224+
{
225+
rocksdb::Checkpoint* checkpoint;
226+
rocksdb::Status status;
227+
228+
status = rocksdb::Checkpoint::Create(m_DbPtr->m_Db, &checkpoint);
229+
230+
if (status.ok()) {
231+
status = checkpoint->CreateCheckpoint(path);
232+
if (status.ok())
233+
{
234+
return work_result(ATOM_OK);
235+
}
236+
}
237+
checkpoint = NULL;
238+
239+
return work_result(local_env(), ATOM_ERROR, status);
240+
} // operator()
241+
242+
}; // class CheckpointTask
243+
200244
/**
201245
* Background object for async write
202246
*/

src/erocksdb.erl

+11
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
-export([iterator/2, iterator/3, iterator_with_cf/3, iterator_move/2, iterator_close/1]).
3232
-export([fold/4, fold/5, fold_keys/4, fold_keys/5]).
3333
-export([destroy/2, repair/2, is_empty/1]).
34+
-export([checkpoint/2]).
3435
-export([count/1, count/2, status/1, status/2, status/3]).
3536

3637
-export_type([db_handle/0,
@@ -473,6 +474,16 @@ destroy(_Name, _DBOpts) ->
473474
repair(_Name, _DBOpts) ->
474475
erlang:nif_error({error, not_loaded}).
475476

477+
478+
async_checkpoint(_Callerfef, _DbHandle, Path) ->
479+
erlang:nif_error({error, not_loaded}).
480+
481+
checkpoint(DbHandle, Path) ->
482+
CallerRef = make_ref(),
483+
async_checkpoint(CallerRef, DbHandle, Path),
484+
?WAIT_FOR_REPLY(CallerRef).
485+
486+
476487
%% @doc
477488
%% Return the approximate number of keys in the default column family.
478489
%% Implemented by calling GetIntProperty with "rocksdb.estimate-num-keys"

0 commit comments

Comments
 (0)