Skip to content

Expose RocksDB Checkpoint API as createCheckpoint(path) #577

@kriszyp

Description

@kriszyp

Summary

Add a thin native method that exposes RocksDB's Checkpoint::CreateCheckpoint API so callers can produce a hardlinked, point-in-time, fully independent copy of an open database.

Motivation

Needed by HarperFast/harper to implement a "branched databases" feature for application isolation (umbrella issue to follow). RocksDB Checkpoint is the right primitive because:

  • It produces a writable sibling DB (not a read-only snapshot).
  • It is near-instant — SST files are hardlinked, only memtable contents are flushed/copied.
  • It is safe to call on a live, actively-written database — that's exactly what the C++ API is designed for.

Reimplementing this in JS (flush + manual hardlink + manifest copy) is fragile compared to using the upstream primitive.

Proposed API

JS surface on RocksDatabase:

```ts
db.createCheckpoint(targetPath: string): Promise
```

  • `targetPath` must not exist (RocksDB requires this).
  • Resolves once the checkpoint has been written; rejects with a Status-derived error on failure.
  • Caller is responsible for opening the checkpoint as a new `RocksDatabase` and for eventual cleanup of the directory.

Native sketch

```cpp
Napi::Value RocksDatabase::CreateCheckpoint(const Napi::CallbackInfo& info) {
std::string path = info[0].AsNapi::String();
rocksdb::Checkpoint* checkpoint;
rocksdb::Status s = rocksdb::Checkpoint::Create(db_, &checkpoint);
if (!s.ok()) { /* throw / }
std::unique_ptrrocksdb::Checkpoint guard(checkpoint);
s = checkpoint->CreateCheckpoint(path);
if (!s.ok()) { /
throw with s.ToString() */ }
return info.Env().Undefined();
}
```

Run the actual checkpoint call on the worker pool (Napi AsyncWorker) so the Node main thread is not blocked — the call can take a few hundred ms when memtables need flushing.

Acceptance criteria

  • `createCheckpoint()` exposed on `RocksDatabase`.
  • Async; runs off the main thread.
  • Failure modes (target exists, parent dir missing, ENOSPC, permission denied) surface as JS errors with the RocksDB status message.
  • Unit test: open DB, write keys, checkpoint, open checkpoint, assert identical reads, write divergent keys in each, assert isolation.

Out of scope

  • Column-family selection (use the full DB).
  • Incremental / differential checkpoints.

🤖 Filed by Claude on behalf of Kris

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions