Docs: without CELLD_NODE, or with one node restarted alone, a restart after a fleet-wide fence loses acknowledged writes or wedges recovery
EfficiencyCorp opened ·
## Summary
On v0.6.0, a restart after a fleet-wide fence either declares a loss of acknowledged writes or wedges recovery indefinitely, depending on which node comes back first, unless every node keeps its `CELLD_NODE` id **and** the whole fleet restarts together within the witness grace. The docs do not say this. `docs/README.md` (L1034) describes `CELLD_NODE` only as "An explicit node-session ID"; the only hint that ids must persist is in the upgrade steps (`docs/guarantees.md` L417-418: "Keep the node names, peer addresses, and data directories for the restart").
## Setup
- celld v0.6.0 `x86_64-unknown-linux-gnu` (release digest verified), fleet durability (the default), two nodes on two dedicated x86 VMs (1 vCPU, 2 GB, Ubuntu 24.04) on a private network, MinIO on a third VM (`celld diagnose`: `ok bucket conditional write: create, reject-create, update, reject-stale`). - One cell, one sequential client writing 1 KiB rows that each carry a unique token; every acknowledged token is logged and later matched by content on read-back. - Store outage: `iptables -I INPUT -p tcp --dport 9000 -j DROP` on the MinIO host for 30 s. Both nodes log `SELF-FENCE: node lease not renewed within TTL` about 10 s in. - Fresh bucket prefix and work directories per run. Synthetic data only.
## Observed
| Node ids | Restart after the outage | Runs | Acknowledged writes lost | |---|---|---|---| | default (no `CELLD_NODE`) | owner first, follower still down | 3 | 1,291 / 1,300 / 1,400 of about 6,100; logs `declared bounded loss: no complete true witness for an active log` | | default | follower first | 4 | none served: `no complete true witness among {...} and 1 member(s) undecided; refusing to seal while member state remains unverified` for 10.5 to 26.5 min until stopped; restarting the follower with its **old** id on the same disk recovered every write in under 1 s | | stable `CELLD_NODE`, systemd supervisor | whole fleet (outage, SIGKILL of the owner, hard power-off of both VMs) | 5 | 0 | | stable `CELLD_NODE` | owner alone, follower down past about 30 s (3 x TTL) | 4 | 1,352 to 1,658 | | stable `CELLD_NODE` | owner and follower started 1 to 2 s apart | 1 | 1,597 (the follower came up after the owner's boot-time check) |
## Suggested docs
1. Recommend a stable `CELLD_NODE` per machine plus a persistent `CELLD_WATCH`, and say what the default random id does on restart. Note that restart policies that mint a new id per restart (the supervisor section names Docker restart policies) hit this. 2. Document the witness grace (max(3 x TTL, 20 s)) and that a node restarted alone after it expires records a loss, even with stable ids. 3. Document what a loss record means for readers (see the companion issue about seq reuse), and an operator path for the "refusing to seal" wedge.
Companion issue for the behaviour side: #245
EfficiencyCorpreferenced this in A declared bounded loss reuses the seqs of acknowledged writes; a 3-node fleet keeps a one-follower ensemble; no operator path out of 'refusing to seal' #245last month on GitHub