Recovering an unmaterialized Shared Volume create
Recovering an unmaterialized Shared Volume create
Filesystem recovery inventories every non-deleted canonical quota root, including failed creates. A failed control-plane row is not proof that its directory or quota is absent. Do not skip that root or clear its database fence.
Before canonical roots have been captured, a Development administrator may ask the original create host for an exact no-materialization cancellation:
POST /v1/admin/juicefs/operations/<original-create-operation-id>/resolve
{
"action": "cancel",
"incident_id": "<current-filesystem-recovery-incident-id>",
"source_host_id": "<current-filesystem-recovery-source-host-id>",
"lease_id": "<current-filesystem-recovery-lease-id>"
}Read the current tuple from the filesystem-recovery admin endpoint. Admission
requires the exact original failed/uncertain create, a failed volume at its
original generation and namespace, a fresh enrolled original host, and no
attachment, snapshot, or other lifecycle history. The epoch must remain
manual_required or quiescing with no roots_fenced_at.
An accepted request returns 202; it does not delete filesystem data or clear
the global incident. It queues volume.juicefs_status with
cancelUnmaterialized: true against the same original operation ID. The host
must exclude concurrent original-create execution, prove the directory, quota,
and every writer/transport fence absent, and persist a cancellation tombstone
that also prevents delayed create redelivery. A missing receipt, a successful
create receipt, or unknown/partial materialization cannot supply that proof.
Only an identity-bound cancelled receipt with current unmaterialized: true
evidence changes the operation to cancelled and the volume to deleted.
Completion rechecks the epoch before changing the canonical inventory. The
global filesystem fence stays active and proceeds through its ordinary full
recovery protocol. A repeated accepted request is idempotent; a manual host
refusal keeps every fence until a subsequent explicit, exact retry can prove
absence. Lost responses replay the same cancellation authority, never create.
Behavioral PostgreSQL coverage lives in
apps/api/src/juicefsUnmaterializedCreate.int.test.ts, including simultaneous
requests, stale identities, existing dependency history, forged or stale
receipts, response loss, manual retry, and a root-capture race.