Skip to main content
RunBook Academy

CephCXIV · Complete Storage Node LossComplete Storage Node Loss

Whether the rebuild can finish at all

Advanced⏱ ~18 minceph

What you'll learn

  • Determine whether the surviving topology can satisfy the placement rule
  • Distinguish a slow rebuild from one that can never complete
  • Assess what a second concurrent failure would do right now
  • Express the exposure window as a decision input

Prerequisites

None — start here.

Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18

Not yet marked complete on this device.

Why this matters in production

After a permanent node loss the cluster either rebuilds to full redundancy or it does not, and the answer is arithmetic you can do in two minutes. Waiting to find out costs days of exposure.

The placement question comes first

ceph osd pool ls detail | grep -E 'replicated|erasure'
ceph osd crush rule dump | python3 -c '
import sys,json
for r in json.load(sys.stdin):
    types = [s.get("type") for s in r["steps"] if s.get("op","").startswith("chooseleaf")]
    print("%-20s failure domain: %s" % (r["rule_name"], types or "?"))'
# how many hosts still carry up OSDs
ceph osd tree --format json | python3 -c '
import sys,json
d = json.load(sys.stdin)
byid = {n["id"]: n for n in d["nodes"]}
live = {n["name"] for n in d["nodes"] if n.get("type") == "host"
        and any(byid.get(c, {}).get("status") == "up" for c in n.get("children", []))}
print(len(live), "hosts with up OSDs:", " ".join(sorted(live)))'
Surviving hostsRuleResult after losing one host
4, size=3, domain hostreplicatedrebuilds to clean
3, size=3, domain hostreplicatedpermanently undersized, still serving
2, size=3, domain hostreplicatedundersized and one failure from inactive
5, EC 4+2, domain hosterasurepermanently undersized at 5 shards
6, EC 4+2, domain hosterasurerebuilds to clean
any, size=3, domain osdreplicatedrebuilds, but copies may share a host

Reading the answer out of the cluster

ceph pg ls undersized | head -5
ceph health detail | grep -A3 PG_DEGRADED
active+undersized+degraded  is serving reads and writes with fewer copies
active+undersized+degraded+remapped+backfilling  is repairing
active+undersized+degraded  with no backfill and no progress  is stuck
# stuck means the rule cannot place the missing copy
ceph pg ls undersized --format json | python3 -c '
import sys,json
d = json.load(sys.stdin)
pgs = d.get("pg_stats", d) if isinstance(d, dict) else d
print(len([p for p in pgs if "backfilling" not in p.get("state","")]), "not backfilling")'

What a second failure would do now

ceph osd pool get rbd-vms min_size
ceph pg ls degraded | wc -l
Current stateNext OSD failure in the same PG
size=3, two copies, min_size=2drops to one copy — IO blocks on those PGs
size=3, two copies, min_size=1serves from one copy, no redundancy at all
EC 4+2, five shards, min_size=5drops to four — those PGs go inactive
rebuilt to three copiestolerated normally
min_size=1 is not a safety setting. It converts an availability outage
into a silent single-copy window, and the next failure is data loss.

The exposure window is a decision input

ceph osd ok-to-stop osd.22
ceph -s | grep -E 'degraded|misplaced'
ActivityDuring the window
Unrelated host rebootspostpone
Firmware or kernel updatespostpone
Adding unrelated capacitypostpone; it competes for the same backfill
Replacement hardware procurementaccelerate

Quiz

Knowledge check · 4 questions

  1. Q1. A three-host cluster with `size=3` and a host failure domain loses one host. PGs sit `active+undersized+degraded` with no backfill. What is happening?

  2. Q2. Setting `min_size=1` on a degraded pool converts a potential availability outage into a window where the next failure is data loss.

  3. Q3. Assess redundancy after a permanent node loss.

    A five-host cluster runs replicated pools at `size=3` and one EC 4+2 pool, both with a host failure domain. One host is permanently lost.

  4. Q4. How do you tell a slow rebuild from one that can never complete?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Count surviving failure domains against every pool’s rule before tuning anything — a rebuild that cannot place its last copy will not respond to recovery settings, and the two states look identical in ceph -s. Treat the exposure window as a freeze on unrelated maintenance, and reach for min_size=1 only as a deliberate, time-boxed availability trade.

Cross-course references

  • Kubernetes: a PodDisruptionBudget that cannot be satisfied blocks rather than degrading quietly
  • Linux: an array below its minimum member count refuses to assemble rather than guessing