Datalevin store-open self-heal. Classify an LMDB open failure and apply a
recovery policy so the store returns to health without operator action.
heal-and-open! composes classification + policy + the caller's open-fn;
it never opens the db itself, keeping this ns driver-agnostic at compile time.
Datalevin store-open self-heal. Classify an LMDB open failure and apply a recovery policy so the store returns to health without operator action. `heal-and-open!` composes classification + policy + the caller's `open-fn`; it never opens the db itself, keeping this ns driver-agnostic at compile time.
(classify-open-failure ex)Classify a Throwable raised by an LMDB-level open. Returns one of
:wal-corrupt, :lock-contention, :version-mismatch, :unknown.
Walks the cause chain so a wrapping exception still classifies correctly.
A failure raised before the store file is read (JVM shutdown refusing
datalevin's shutdown hook: Shutdown in progress) classifies
:not-corruption, ahead of every other class: it says nothing about the
store's content and must never feed a recovery rung.
Classify a Throwable raised by an LMDB-level open. Returns one of `:wal-corrupt`, `:lock-contention`, `:version-mismatch`, `:unknown`. Walks the cause chain so a wrapping exception still classifies correctly. A failure raised before the store file is read (JVM shutdown refusing datalevin's shutdown hook: `Shutdown in progress`) classifies `:not-corruption`, ahead of every other class: it says nothing about the store's content and must never feed a recovery rung.
(dead-conn-throwable? ex)True when ex indicates the operation ran against a closed conn/env —
ClosedChannelException anywhere in the cause chain, datalevin's (conn? conn) assertion, or a 'closed' storage message. Corruption and domain
errors return false; they must surface, not heal.
True when `ex` indicates the operation ran against a closed conn/env — ClosedChannelException anywhere in the cause chain, datalevin's `(conn? conn)` assertion, or a 'closed' storage message. Corruption and domain errors return false; they must surface, not heal.
Operator-tunable default. :strategy may be a single keyword or a vector of
keywords; a vector is tried left-to-right per failure until one returns
:retry. :max-attempts is a positive int.
Operator-tunable default. `:strategy` may be a single keyword or a vector of keywords; a vector is tried left-to-right per failure until one returns `:retry`. `:max-attempts` is a positive int.
(heal-and-open! {:keys [policy db-path]} open-fn)Attempt (open-fn). On failure, classify, apply policy, retry up to
:max-attempts total attempts. A failure classified :unknown is never
retried: the thrown ex-data carries :retryable? false. Returns the conn value or rethrows the last
exception with :classification in its ex-data.
Only a classification in healable-classifications reaches the policy at
all. :unknown and :not-corruption (e.g. Shutdown in progress) abort
on the first failure with zero recovery rungs run, so neither can ever walk
a ladder into :truncate or :quarantine.
policy — see default-policy:
:strategy keyword | [keyword ...] from #{:throw :audit :truncate :quarantine}
:max-attempts positive int (default 2)
db-path is the directory open-fn opens; a policy may mutate that on-disk
state before re-invoking open-fn. open-fn is a 0-arg thunk producing the
conn — a thunk (not a fixed datalevin call) keeps this ns storage-agnostic.
Attempt `(open-fn)`. On failure, classify, apply policy, retry up to
`:max-attempts` total attempts. A failure classified `:unknown` is never
retried: the thrown ex-data carries `:retryable? false`. Returns the conn value or rethrows the last
exception with `:classification` in its `ex-data`.
Only a classification in `healable-classifications` reaches the policy at
all. `:unknown` and `:not-corruption` (e.g. `Shutdown in progress`) abort
on the first failure with zero recovery rungs run, so neither can ever walk
a ladder into `:truncate` or `:quarantine`.
`policy` — see `default-policy`:
:strategy keyword | [keyword ...] from #{:throw :audit :truncate :quarantine}
:max-attempts positive int (default 2)
`db-path` is the directory `open-fn` opens; a policy may mutate that on-disk
state before re-invoking `open-fn`. `open-fn` is a 0-arg thunk producing the
conn — a thunk (not a fixed datalevin call) keeps this ns storage-agnostic.Classifications positively identified from the failure itself. Only these
may reach a recovery rung (:truncate, :quarantine, a strategy fn) or a
retry. :unknown and :not-corruption are absent on purpose: a failure we
cannot name, or one raised before the store was read, must never mutate a
store that may be healthy (Never-NUKE-Data, axiom 20260428102603-3c7a5aff).
Classifications positively identified from the failure itself. Only these may reach a recovery rung (`:truncate`, `:quarantine`, a strategy fn) or a retry. `:unknown` and `:not-corruption` are absent on purpose: a failure we cannot name, or one raised before the store was read, must never mutate a store that may be healthy (Never-NUKE-Data, axiom 20260428102603-3c7a5aff).
(jvm-shutting-down?)True once JVM shutdown has begun. Probes by registering and removing a
no-op shutdown hook: Runtime.addShutdownHook throws IllegalStateException
after shutdown starts, which is the same refusal that makes a datalevin
open fail with Shutdown in progress. Never throws.
True once JVM shutdown has begun. Probes by registering and removing a no-op shutdown hook: `Runtime.addShutdownHook` throws IllegalStateException after shutdown starts, which is the same refusal that makes a datalevin open fail with `Shutdown in progress`. Never throws.
(quarantine! db-path)(quarantine! db-path target-path)Move the db directory aside to quarantine-path. Returns the new path on
success, nil if the source doesn't exist. Throws on IO failure.
Move the db directory aside to `quarantine-path`. Returns the new path on success, nil if the source doesn't exist. Throws on IO failure.
(quarantine-path db-path)(quarantine-path db-path ts)Derive the quarantine path for db-path. Deterministic given a timestamp;
defaults to System/currentTimeMillis for live calls.
Derive the quarantine path for `db-path`. Deterministic given a timestamp; defaults to `System/currentTimeMillis` for live calls.
(retryable-classification? classification)True when an open failure of classification may be re-attempted. An
:unknown failure never is, whatever the policy answers; neither is a
:not-corruption failure (JVM shutdown), which no rung can fix.
True when an open failure of `classification` may be re-attempted. An `:unknown` failure never is, whatever the policy answers; neither is a `:not-corruption` failure (JVM shutdown), which no rung can fix.
(truncate-tail! db-path)(truncate-tail! db-path ts)Walk the txn-log segment directory under db-path. For each segment whose
strict scan fails but lenient scan reports :partial-tail? true, copy it
aside and invoke datalevin's truncate-partial-tail!. Returns a vec of
per-segment heal records; empty means no segment needed truncation.
Walk the txn-log segment directory under `db-path`. For each segment whose strict scan fails but lenient scan reports `:partial-tail? true`, copy it aside and invoke datalevin's `truncate-partial-tail!`. Returns a vec of per-segment heal records; empty means no segment needed truncation.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |