CephXCIX · Upgrade PlanningUpgrade Planning
The post-upgrade watch period
What you'll learn
- Run the immediate post-upgrade verification
- Identify what emerges over a longer period
- Know what to watch over days
- Decide when the upgrade is complete
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
Why this matters in production
Some upgrade problems appear in seconds and some in days, and declaring completion at the first checkpoint misses the second kind.
Immediately
ceph orch upgrade status # in_progress false
ceph versions # one version everywhere
ceph -s # HEALTH_OK
ceph health detail
ceph pg stat # all active+clean
ceph osd tree | grep -c up
# and the client path actually works
POOL=rbd-vms
rbd ls ${POOL} >/dev/null && echo "rbd OK"
ceph fs status
| Check | Expected |
|---|---|
ceph versions | a single version per daemon type |
ceph -s | HEALTH_OK |
| PG states | all active+clean |
| OSDs up | matches the total |
| Client operations | succeed |
Over the first hours
watch -n 60 'ceph -s | grep -E "health|pgs|io"; \
ceph health detail | head -5'
| Signal | Meaning |
|---|---|
| Slow ops appearing | a daemon behaving differently under load |
| Latency above baseline | a performance regression |
| Health checks appearing intermittently | something not settled |
| Client errors | a compatibility issue |
| Memory growth on a daemon | a possible leak in the new version |
# compare against the baseline captured before
ceph osd perf
diff <(ceph config dump) /backups/ceph-pre-upgrade/config.txt
# daemon memory, for the leak case
ceph orch ps --format json | python3 -c '
import sys,json
for d in json.load(sys.stdin):
m = d.get("memory_usage")
if m: print("%-24s %8.1f MiB" % (d["daemon_name"], m/1048576))' | sort -k2 -rn | head
Over days
| Signal | Why it takes days |
|---|---|
| Deep scrub results | the scrub cycle is days long |
| Memory growth | a slow leak needs time to be visible |
| Capacity trend changes | requires a trend |
| Rare code paths | some operations occur infrequently |
| Snapshot and trim behaviour | driven by the retention schedule |
# deep scrub coverage since the upgrade
ceph pg dump pgs --format json 2>/dev/null | python3 -c '
import sys,json
pgs = json.load(sys.stdin)
pgs = pgs.get("pg_stats", pgs)
print("PGs:", len(pgs))
print("with scrub errors:", sum(1 for p in pgs if p.get("stat_sum",{}).get("num_scrub_errors",0)))'
The first full deep scrub cycle after an upgrade is a meaningful
checkpoint: it reads every object and compares replicas, which is the
strongest available statement that nothing was damaged.
Declaring completion
The upgrade is complete when:
one version everywhere and HEALTH_OK — immediately
no regression against the baseline — hours
a full deep scrub cycle has passed clean — days
no daemon memory trend — days
the release's known issues have not appeared — days
ceph versions
ceph -s
Only then is the next cluster's upgrade reasonable to schedule.
Quiz
Knowledge check · 4 questions
Q1. Why is a full deep scrub cycle a meaningful post-upgrade checkpoint?
Q2. A daemon memory comparison against the pre-upgrade baseline is only meaningful when both sides are at steady state.
Q3. Decide when an upgrade is complete.
An upgrade finished four hours ago. `ceph versions` shows one version, the cluster is HEALTH_OK, and performance matches the baseline. The team asks whether the next cluster can be scheduled.
Q4. Which post-upgrade signals only emerge over days rather than hours?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Allow a full deep scrub cycle between staged cluster upgrades — it reads every object and compares replicas, and it is the strongest evidence the upgrade damaged nothing. Compare daemon memory steady state to steady state; the post-restart cache refill looks identical to a leak for hours.
Cross-course references
- Kubernetes: post-upgrade soak periods exist for the same slow-signal reason
- Linux: memory leak detection requires reaching steady state before comparing