package granary
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=8b18780ea373be48301d9f333925860a2f9110fc0ac28684295118d72b65a67e
sha512=25ca3c9c5e2b528704a542502e0f37dc33ba003f65622d969b8c2b800778585f8ef0cf89b36e6679832e3993e8303aecddfc662742baf7044d6afe4a796b8f11
doc/granary.storage/Granary_storage/Header/index.html
Module Granary_storage.HeaderSource
Alternating two-header commit protocol for crash safety. Pages 0 and 1 hold the two alternating file headers. The header with the higher txn_id and valid CRC is the live state.
type encryption = {canary_nonce : string;(*16 bytes at header bytes 72–87
*)canary_tag : string;(*16 bytes at header bytes 88–103
*)
}Encryption marker and key-check canary persisted in the header (#84).
type t = {txn_id : int64;root_page : int64;freelist_page : int64;n_pages_total : int64;schema_version : int64;format_version : int32;(*On-disk format version (#174). Preserved across commits; only a fresh
*)initstampscurrent_format_version.geom : Geometry.t;(*Page geometry persisted in the header (#95): page_size + reserved bytes, fixed at creation, preserved verbatim across commits.
*)enc : encryption option;(*Encryption marker and key-check canary (#84).
*)Nonefor plaintext databases;Some _when the "SENC" magic is present on disk.
}On-disk format version this build writes for freshly-initialised databases. v1 = pre-#174 (no fingerprints); v2 = #174 (schema fingerprints, redundant catalog mirror, per-page fingerprint stamp).
Highest on-disk format version this build can open. read_live fails with Unsupported_format for any database stamped above this.
Pretty-print all header fields.
Pretty-print an error.
#95 bootstrap: discover a file's page geometry from the leading bytes of page 0 (page_size at byte 56, reserved at byte 64) WITHOUT verifying the CRC — the CRC covers the whole real page, whose size is what we're trying to learn. Pass at least the first 68 bytes of page 0 (a default 4096-byte read suffices). Returns None for a fresh/zeroed page or garbage, in which case the caller uses a supplied/default geometry. Once the geometry is known, read_live re-reads and CRC-verifies the full header pages.
Read both headers (pages 0 and 1) from the pager. Pick the live one: the valid header (passes CRC) with the higher txn_id. If one is corrupt and the other valid, use the valid one. Returns Error Both_headers_corrupt if neither passes CRC.
Commit a new header state. Writes to the INACTIVE header page (the one NOT used by prev_header), computes and seals CRC, then calls Pager.flush (which writes all dirty pages + syncs). The txn_id of the new header is prev_header.txn_id + 1. new_state provides root_page, freelist_page, n_pages_total, schema_version.
Like commit but defers the device sync to a later Pager.wal_sync. Stages the next header into its inactive slot and pushes all dirty pages through Pager.flush_no_sync; group-commit callers coalesce the actual fsync across multiple writers. On non-WAL backends this falls through to the regular sync flush, so it is safe to call regardless of backend.
Initialise a brand-new empty file: write both header pages with txn_id=0 and zeroed root/freelist. Called once on new file creation. After init, a subsequent read_live returns the zeroed header. ?enc sets the encryption marker and canary on the freshly-created DB (None by default — plaintext).