Opening a database
A RocksDB database is a directory on disk that contains SST files, the WAL, the manifest, and the OPTIONS file. To get a handle to it you call one of the static RocksDb.Open* methods with a DbOptions instance and a path.
using RocksDbSharp;
var options = new DbOptions().SetCreateIfMissing(true);
using var db = RocksDb.Open(options, "/var/lib/myapp/state");
Always wrap the returned RocksDb in using so the handle is released and pending writes are flushed.
The five open modes
RocksDB-Sharp exposes every open mode the engine supports. Pick the one that matches the lifecycle you need.
| Mode | Method | Use it for |
|---|---|---|
| Read-write (primary) | RocksDb.Open(options, path) |
The default. One process at a time. |
| Read-only | RocksDb.OpenReadOnly(options, path, errorIfLogFileExists) |
Multiple concurrent readers of a static DB. |
| Secondary | RocksDb.OpenAsSecondary(options, path, secondaryPath) |
Live follower of a primary, can TryCatchUpWithPrimary(). |
| TTL | RocksDb.OpenWithTtl(options, path, ttlSeconds) |
Keys auto-expire after ttlSeconds. |
| With column families | RocksDb.Open(options, path, columnFamilies) and variants |
DBs that use multiple column families. |
The read-only and secondary modes are documented in detail on the upstream Read-only and Secondary instances wiki page. TTL semantics are on the Time-to-Live wiki page.
Primary (read-write)
The everyday case. Exactly one process can hold the lock at a time — RocksDB throws if a second process tries to open the same directory.
var options = new DbOptions()
.SetCreateIfMissing(true)
.SetCreateMissingColumnFamilies(true)
.IncreaseParallelism(Environment.ProcessorCount);
using var db = RocksDb.Open(options, "/var/lib/myapp/state");
Read-only
Open the database without taking the lock. Useful for ad-hoc inspection, sidecar tools, or fanning out queries to multiple processes.
using var db = RocksDb.OpenReadOnly(
new DbOptions(),
"/var/lib/myapp/state",
errorIfLogFileExists: false);
string v = db.Get("hello");
errorIfLogFileExists: true makes the open fail if the WAL has unflushed entries — a safety net when you want a guaranteed-clean view.
Secondary (live follower)
A secondary instance attaches to a primary's directory in read-only mode but can be brought up to date by calling TryCatchUpWithPrimary(). Each secondary needs its own secondaryPath for tail-state.
using var follower = RocksDb.OpenAsSecondary(
new DbOptions(),
primaryPath: "/var/lib/myapp/state",
secondaryPath: "/var/lib/myapp/follower");
// Periodically re-sync with the primary
follower.TryCatchUpWithPrimary();
string v = follower.Get("hello");
For an end-to-end example using WAL streaming for sub-second replication, see the Replication guide.
TTL database
Keys older than ttlSeconds are eligible for compaction-time deletion. TTL is not an exact-expiry mechanism — it kicks in during compaction.
using var db = RocksDb.OpenWithTtl(
new DbOptions().SetCreateIfMissing(true),
"/var/lib/myapp/cache",
ttlSeconds: 60 * 60 * 24); // one day
See the TTL database guide for caveats.
With column families
If the database uses column families (anything beyond "default"), every Open call must enumerate them up front.
var cfs = new ColumnFamilies
{
{ "users", new ColumnFamilyOptions() },
{ "orders", new ColumnFamilyOptions() },
};
using var db = RocksDb.Open(
new DbOptions().SetCreateIfMissing(true).SetCreateMissingColumnFamilies(true),
"/var/lib/myapp/state",
cfs);
var users = db.GetColumnFamily("users");
var orders = db.GetColumnFamily("orders");
db.Put("u:42", "Ada", users);
The full guide is on the Column Families page. Upstream reference: Column Families wiki.
Listing column families before opening
If you don't know which column families exist, ask:
foreach (var name in RocksDb.ListColumnFamilies(new DbOptions(), path))
{
Console.WriteLine(name);
}
// Non-throwing variant
if (RocksDb.TryListColumnFamilies(new DbOptions(), path, out var names))
{
foreach (var n in names) Console.WriteLine(n);
}
Cleaning up
RocksDb implements IDisposable. Disposing it:
- Releases every cached
ColumnFamilyHandle. - Calls
rocksdb_close, which flushes the MemTable and closes the WAL. - Suppresses finalization so the unmanaged handle can't be double-freed.
using (var db = RocksDb.Open(options, path))
{
// …
} // Dispose runs here.
If you can't use using (e.g. the DB outlives a single scope), call db.Dispose() explicitly during application shutdown.
Don't share `RocksDb` across processes
The directory is locked by the primary instance. Use secondary instances for multi-process read access, not multiple primaries.
Inspecting an open database
A few useful properties / methods once you have a RocksDb:
db.Path; // the data directory
db.WalPath; // configured WAL dir (if any)
db.LogPath; // configured info-log dir (if any)
db.GetProperty("rocksdb.stats"); // human-readable stats
db.GetProperty("rocksdb.estimate-num-keys"); // est. key count
db.GetProperty("rocksdb.estimate-pending-compaction-bytes");
db.GetLatestSequenceNumber(); // current sequence number
db.GetLiveFileNames(); // active SST files
db.GetLiveFilesMetadata(); // full metadata for each
The full set of property names is documented on the Property reference wiki page.