Expand description
kevy-persist — durability for a kevy_store::Store.
Two mechanisms, both zero-dependency pure Rust over std::fs:
- Snapshot (RDB-style):
save_snapshotdumps a whole store to a temp file then atomically renames it (fsync before rename);load_snapshotrestores it. A compact, type-tagged binary format. - AOF: an
Aofappend-only command log with a configurable fsync policy;replay_aofre-applies it on startup, tolerating a truncated trailing frame from a crash mid-write.
In a shared-nothing runtime each shard persists its own store to its own file, so there is no cross-core coordination. Part of the kevy server.
§Example (AOF)
use kevy_persist::{Aof, Argv, Fsync, replay_aof};
let path = std::env::temp_dir().join("kevy-persist-doctest.aof");
{
let mut aof = Aof::open(&path, Fsync::No)?;
aof.append(&Argv::from(vec![b"SET".to_vec(), b"k".to_vec(), b"v".to_vec()]))?;
} // flushed on drop
let mut replayed: Vec<Argv> = Vec::new();
replay_aof(&path, |args| replayed.push(args))?;
assert_eq!(replayed, vec![vec![b"SET".to_vec(), b"k".to_vec(), b"v".to_vec()]]);Modules§
- layout
- Per-shard persistence file naming — the single source of truth for the on-disk layout. Every kevy data dir is a flat set of per-shard files:
- reshard
- Crash-safe shard-layout migration — the shared engine behind the server runtime’s and the embedded store’s re-shard paths.
Structs§
- Aof
- An append-only command log. Each write command is appended as a RESP
multi-bulk frame;
crate::replay_aofre-applies them on startup. - Argv
- A parsed command’s argument vector.
- Rewrite
Plan - Handoff between the two halves of a non-blocking rewrite: the serialized
keyspace image (produced under the store lock) and the temp path to spill
it to (off-lock). See
Aof::begin_concurrent_rewrite. - Rewrite
Stats - Result of an
Aof::rewrite_fromcall. Surfaced byBGREWRITEAOF/INFO persistence. - Shards
Meta - The shard layout a data dir’s per-shard files were written under.
Enums§
Traits§
- Argv
View - Read-only view over a parsed command’s argument vector.
- Snapshot
Source - Anything that can enumerate
(key, &Value, ttl_ms)triples for serialization: a liveStore(itssnapshot_each, the synchronous paths) or a frozenkevy_store::SnapshotView(the COW paths — collect on the owning thread, serialize on a background one).
Functions§
- dump_
aof - Write
src’s state (a live [Store] or a frozenkevy_store::SnapshotView) topathas a sequence of mutating RESP commands prefixed with [crate::aof::AOF_MAGIC]; flush + fsync before returning. Returns(keys, bytes). The magic header is consistent withAof::open’s fresh-file behavior so BGREWRITEAOF-produced files replay the same way live-appended ones do. - load_
snapshot - Load a snapshot from
pathintostore(entries are inserted, not cleared first — call on a fresh store). Errors on a bad magic/version or truncation. - read_
shards_ meta - Read
shards.metafrompath.None= no meta / unparseable (callers treat the dir as a legacy layout). A v1 single-number file reads asRouting::KevyHash; an unknown routing tag is not guessed at — the file came from a newer kevy, so we fall back toNoneand the caller’s lossless legacy path rather than misroute every key. - replay_
aof - Replay the command log at
path, callingapplyfor each complete command. - save_
snapshot - Write a point-in-time snapshot of
src(a liveStoreor a frozenkevy_store::SnapshotView) topath, atomically: data is written to<path>.tmp, fsynced, then renamed overpath. - write_
aof_ base - Write a fresh AOF base at
path: just the magic header, fsynced. The COW background-save’s log reset starts from this — the post-collect tee’d writes are appended byfinish_concurrent_rewriteand the result swaps over the live AOF (the snapshot now carries the pre-collect state). - write_
shards_ meta - Write
shards.metatopath(v2: count, then routing tag). - write_
snapshot_ tmp - The write half of
save_snapshot: produce the durable (fsynced)<path>.tmpand return its path without the final rename. For the COW background-save flow: the serializer thread writes the temp file at leisure, then the store-owning thread renames it in the same critical section that resets the AOF — keeping the snapshot/AOF commit adjacent instead of seconds apart.