Operations
Checkpoints of a live database, verifying every block, removing a database safely, the statistics it counts, and the errors it returns with what to do about each.
Checkpoints
Db::checkpoint(dir) writes a consistent copy of a live database into another
directory. The copy holds every batch committed before the call. It opens as a
database of its own, with the same options and the same key provider when
encrypted.
use tessarikv::Db;
async fn backup(db: &Db) -> tessarikv::Result<()> {
db.checkpoint("backups/2026-10-17").await
}
The batches still in memory are flushed first. Then the table files of that
moment are copied with a manifest naming them, so the copy needs no log. Reads
and writes go on meanwhile. dir must be empty or absent. A database in memory
cannot be checkpointed.
Verifying a database
Db::verify_checksums() re-reads every table file from storage and verifies
each block's checksum. It fails with a Corruption error naming the file and
offset. Data that fails it needs restoring, not retrying.
Removing a database
Db::destroy(path) removes every file the engine wrote in a database's
directory, in an order a crash cannot turn into a partial database. It refuses a
database that is open.
Statistics
Turn them on with DbOptions::builder().statistics(true); read them with
Db::statistics(), which returns None when they are off.
use tessarikv::{Db, Histogram, Ticker};
fn report(db: &Db) {
if let Some(stats) = db.statistics() {
let hits = stats.ticker(Ticker::BlockCacheHit);
let misses = stats.ticker(Ticker::BlockCacheMiss);
let p99 = stats.histogram(Histogram::GetMicros).quantile(99, 100);
println!("block cache {hits} hits, {misses} misses; get p99 {p99} µs");
}
}
Tickers count since open: GetCalls, MemtableHit, MemtableMiss,
BlockCacheHit, BlockCacheMiss, BlockBytesRead, BloomUseful,
BloomMaybe, KeysWritten, BytesWritten, WalBytes, WalSyncs,
StallMicros, FlushBytes, CompactionBytesRead, CompactionBytesWritten,
CompactionKeysDropped.
Histograms cover the latest interval: GetMicros and WriteMicros.
Each count is one wait-free add on a per-thread stripe, so counting does not make threads contend.
Watching for trouble
Db::background_error()—Someonce a log write, a flush or a compaction failed. Writes are refused until the database is reopened; reads still work.Db::oldest_snapshot()— a sequence far behindSnapshot::sequence()of a new snapshot means something holds an old snapshot, and old versions are piling up on disk.StallMicrosgrowing — compaction is behind. See Compaction and backpressure.
Errors
Every error has a category, Error::category(), that says what to do.
Error::is_retryable() is true for Locked, WriteStalled, Conflict and an
interrupted I/O call.
ErrorCategory | Means | Do |
|---|---|---|
Validation | caller input or options out of range | fix the call |
NotFound | a file the operation needs is missing | check the path |
Conflict | a concurrent write won | re-read and retry |
Unavailable | another holder owns the resource, or writes are stalled | retry later |
Timeout | a bounded wait expired | retry later |
Corruption | stored bytes do not decode or verify | restore the data |
Io | the operating system refused an operation | check the disk |
ReadOnly | writes stopped after a durability failure; reads work | reopen |
ShutDown | the handle is closed | open again |
Internal | the engine broke one of its own invariants | report it |
A Corruption message names where, never the stored bytes, so a log line cannot
leak data.