CephXXII · PG InvestigationPG Investigation
Deep investigation: per-OSD latency and logs
What you'll learn
- Read ceph osd perf and interpret commit and apply latency
- Use ceph daemonperf to watch an OSD live
- Query the OSD admin socket for in-flight operations
- Read OSD logs for the events that matter
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
PG state tells you which OSD is implicated. It never tells you why that OSD is slow. The distinction between a failing disk, a saturated network path, an OSD out of memory, and a RocksDB compaction storm is invisible at the PG layer and obvious one layer down — and they have entirely different fixes.
The cluster-wide latency scan
ceph osd perf
osd commit_latency(ms) apply_latency(ms)
12 891 904
47 11 13
83 9 12
commit_latency is the time to make a write durable; apply_latency is
the time to make it visible. On BlueStore they move together. What you
are looking for is not an absolute value but an outlier — one OSD far
from its peers on the same hardware class.
Watching one OSD live
ceph daemonperf osd.12
This streams a live table of the OSD’s counters. The columns that carry the most signal:
| Column group | Reading it |
|---|---|
osd ops/wr/rd | is it doing any work at all? |
bl (BlueStore) | kv commit and state latencies |
rocksdb | compaction activity |
recovery | how much of its work is recovery |
An OSD with high latency and near-zero op counts is blocked on something. An OSD with high latency and high op counts is simply saturated.
In-flight operations
The admin socket exposes what the OSD is doing right now:
ceph daemon osd.12 ops
ceph daemon osd.12 dump_historic_ops
ceph daemon osd.12 dump_blocked_ops
ops lists in-flight requests with their age and current stage. A
request sitting at waiting for rw locks for seconds is contention; one
at waiting for subops from 47,83 is waiting on peers, which redirects
the investigation to those OSDs. dump_historic_ops shows the slowest
recently-completed operations with per-stage timings — the closest thing
Ceph has to a request trace.
On containerised deployments run these through the orchestrator:
cephadm shell -- ceph daemon osd.12 dump_historic_ops
The log
journalctl -u ceph-osd@12 --since '2 hours ago' | grep -Ei 'slow|error|abort|heartbeat'
The events worth grepping for:
slow request— an operation exceededosd_op_complaint_time, with the stage it was stuck inheartbeat_check: no reply from— the OSD cannot reach a peer, which is a network finding_txc_committeddelays and RocksDB compaction messages — storage-layer pressureosd_mapgaps ormap e... is newer— the OSD is behind on maps
Turn up verbosity only for a bounded window; debug logging is expensive:
ceph tell osd.12 config set debug_osd 10
# ... reproduce ...
ceph tell osd.12 config set debug_osd 0/5
Quiz
Knowledge check · 4 questions
Q1. `dump_historic_ops` on osd.12 shows operations spending most of their time at `waiting for subops from [47,83]`. What does this indicate?
Q2. High latency alongside near-zero operation counts means the OSD is blocked on something rather than busy.
Q3. Localise the cause of one slow OSD.
osd.12 shows 900 ms commit latency in `ceph osd perf` while its 23 peers on identical hardware sit under 15 ms. Several PGs including osd.12 are recovering slowly. The host has 11 other OSDs, all normal.
Q4. Why should debug_osd be raised only for a bounded window?
Passing score: 75%. Answers are checked in this browser.
Production discipline
Capture dump_historic_ops and the relevant log window before
restarting anything — both are lost on daemon restart, and they are the
only artefacts that distinguish the possible causes after the fact. Build
the OSD-latency outlier check into your monitoring so an OSD drifting away
from its peers is detected before it stalls a scrub or a recovery.
Cross-course references
- Kubernetes: this is the container-runtime layer beneath a failing Pod — one level below where the symptom appears
- Linux: dump_historic_ops stage timings are the same technique as reading blktrace or perf stage breakdowns