Recover from host loss¶
Use this runbook when a host disappears while it holds active writers. The goal is to fence the lost host, recover each workspace from its last acknowledged checkpoint, and return capacity to the pool.
Host loss is permanent loss of that host's local state. The local cache, the active mount state, the uncheckpointed upper deltas, and any preserved local recovery deltas on that host are gone. What survives is the immutable truth: imported snapshots, acknowledged checkpoints, workspace metadata, audit events, and retained patch exports. See The durability model.
Leases and fencing prevent split-brain. Every writer lease carries a
monotonic generation. A lost host keeps an old generation. Even if its process
resumes, it cannot publish. See
Fencing and split-brain.
Detect¶
Watch for one or more of these signals:
- The host does not answer
awcctl status. TheGetHostStatushost RPC fails, times out, or refuses the connection. The host's SSH session and health probe also fail. - Renewals for the host's writer leases stop. The control plane still shows
live leases with
host_idequal to the lost host, but theirexpires_atpasses with no renewal. awc_active_writer_leaseskeeps counting the lost host's leases as live. They stay live until a new acquire fences them (see Current scope).- Lifecycle RPCs that target the host fail. A new
awcctl workspace mounton that host returns an error, because the host cannot serve it.
A short partition is not host loss
Confirm the host is gone, not briefly unreachable. A host that recovers on its own needs Handle a stale writer, not this runbook. Wait long enough to rule out a transient network failure.
Procedure¶
-
Mark the lost host unschedulable. Stop your scheduler from sending new mounts to it. This prevents new work from targeting a host that cannot serve it.
-
Confirm the host is lost. Probe
awcctl status, the health endpoint, and SSH. Correlate the failure with the lost host's stalled leases. If the host might return, follow Handle a stale writer instead. -
List the affected workspaces. Query the control-plane database for live leases whose
host_idequals the lost host. Record eachworkspace_id, the acknowledgedhead, and the leasegeneration. -
Wait out the lease TTL (time to live). Renewals from the lost host have stopped. After
expiry_seconds(default90), each lease is past-due and a new acquire can fence it. Do not delete lease rows by hand. -
Confirm the acknowledged checkpoint survived. The workspace
headin PostgreSQL points at a published snapshot. Verify that snapshot's objects are readable in the object store. Only an acknowledged checkpoint is guaranteed to survive host loss. -
Reassign each workspace to a healthy host. Mount the same workspace there, or fork a new workspace from the acknowledged
head.awcctl workspace mount ws_01J... --target /workspace awcctl workspace fork --workspace ws_01J... --from headThe new lease acquire fences the lost host's past-due lease to
EXPIREDand issues the nextgeneration. This is the fence. -
Treat uncheckpointed writes on the lost host as lost. They were never remotely durable. Do not try to make them the head. If the host's disk returns later, you MAY export its upper as an offline patch bundle that never advances the head automatically.
-
Retire the lost host's identity. Once you are sure it will not return, retire it so its mTLS (mutual TLS) identity is no longer honored. A resurrected host then cannot reauthenticate as a trusted writer.
Verify¶
Confirm recovery when all of these hold:
- Each affected workspace has one active writer lease on a healthy host. That
lease holds a
generationhigher than the lost host's. awc_active_writer_leasesshows the expected writer count. No live lease remains on the lost host.- The workspace
headandversionin PostgreSQL match the last acknowledged checkpoint. They are unchanged unless a new checkpoint was published on the replacement host. - A publish attempt with the lost host's old
generationfails withStaleGeneration. No double-write was possible, because only onegenerationcan publish. - The lost host is
UNSCHEDULABLEorRETIREDin the host table.
Impact¶
Uncheckpointed writes on the lost host are lost
Writes that were not checkpointed before the host disappeared are gone. They lived only in the host-local upper directory. They were never remotely durable, and they cannot become the workspace head. The authoritative head is the last acknowledged checkpoint.
Acknowledged checkpoints and metadata survive
Imported snapshots, acknowledged checkpoints, workspace metadata, audit events, and retained patch exports live in the object store and PostgreSQL. Host loss does not touch them. The workspace recovers from its last published head.
No split-brain
The generation fence means the lost host could never have published
alongside the new writer. Even if the old process resumes, its stale
generation is rejected at publication. There is no window in which two
writers advance the same head.
Current scope¶
The build implements the lease-acquire fence and the publication predicate, but some operator surfaces lag. Be aware of these gaps:
- Leases are fenced lazily, not by a background sweeper. A lease moves to
EXPIREDonly when the next writer lease for that workspace is acquired. Waiting out the TTL makes the lease past-due. Step 6 of the procedure performs the fence. There is no timer that auto-expires a lease on its own. - There is no
awcctl host draincommand. Marking a hostUNSCHEDULABLEorRETIREDis a control-plane database or API operation. - Finding workspaces by host is manual. There is no single command that
lists the active leases for a host. Query the
workspace_leasestable for rows with the losthost_idand a live state. - Lease provisioning from the CLI mount path is partial. A session created
by
awcctl workspace mountmay not yet carry alease_id. The fence path applies only to sessions the mount path issued a lease for. See Handle a stale writer. - The
control_planehealth component is not wired. It reportsUnknown, so readiness probes cannot confirm or deny host loss. Detect the loss from the unreachable host and its stalled leases instead. See Recover from a control-plane outage.