TessariDBDocs
  • 0.35.3latest
  • 0.35.2
  • 0.35.1
  • 0.35.0
  • 0.34.4
  • 0.34.3-beta
  • 0.34.2-beta
  • 0.34.1-beta
  • 0.34.0-beta
  • 0.33.4-beta
  • 0.33.3-beta
  • 0.33.2-beta
  • 0.33.1-beta
  • 0.33.0-beta
  • 0.32.0-beta

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() — Some once 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 behind Snapshot::sequence() of a new snapshot means something holds an old snapshot, and old versions are piling up on disk.
  • StallMicros growing — 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.

ErrorCategoryMeansDo
Validationcaller input or options out of rangefix the call
NotFounda file the operation needs is missingcheck the path
Conflicta concurrent write wonre-read and retry
Unavailableanother holder owns the resource, or writes are stalledretry later
Timeouta bounded wait expiredretry later
Corruptionstored bytes do not decode or verifyrestore the data
Iothe operating system refused an operationcheck the disk
ReadOnlywrites stopped after a durability failure; reads workreopen
ShutDownthe handle is closedopen again
Internalthe engine broke one of its own invariantsreport it

A Corruption message names where, never the stored bytes, so a log line cannot leak data.