pgrep -f 'postgres.*-D' -u postgres 能精准获取数据库主进程PID,避免多实例误匹配;配合 pidstat -d 可实时监控 rkB/s 和 wkB/s,数值超15000 KB/s(15 MB/s)提示IO趋近SATA SSD极限,超50000 KB/s则接近NVMe满载。

直接用 pidstat -d 配合精准 PID 获取,就能实时看到数据库进程的磁盘读写速率(rkB/s、wkB/s),这是判断 IO 压力最核心的指标。
确认数据库进程 PID 并避免手动抄错
别用 ps aux | grep postgres 或 pgrep postgres 简单匹配——多实例、容器化部署、启动参数含空格时极易漏掉或误抓。推荐组合:
-
pgrep -f 'postgres.*-D' -u postgres:限定用户 + 匹配主数据目录参数,更贴近真实服务进程 -
pgrep -f 'mysqld.*--datadir' -u mysql:MySQL 同理,用--datadir锚定主实例 - 验证 PID 是否存活:
kill -0 $(pgrep -f 'postgres.*-D') 2>/dev/null && echo "alive"
用 pidstat -d 实时看 IO 读写速度
执行命令后重点关注 rkB/s(每秒读 KB) 和 wkB/s(每秒写 KB),它们是瞬时速率,不是累计值:
-
pidstat -d 1 -p "$(pgrep -f 'postgres.*-D')":每秒刷新一次,适合观察突发 IO -
pidstat -d 5 -p "$(pgrep -f 'mysqld.*--datadir')":5 秒一刷,平滑短期抖动,更适合趋势判断 - 若数值长期高于 15000(≈15 MB/s),说明接近 SATA SSD 极限;超 50000(≈50 MB/s)基本已压满 NVMe
排除干扰项,只盯真正相关的字段
pidstat -d 输出里混着内存列(如 %MEM、RSS)是默认不显示的,但加了 -r 就会一起出来——这些和 IO 完全无关:
- 只看 rkB/s 和 wkB/s:其他列(包括 %MEM、VSZ、CPU 列)都是干扰项,别被排版误导
- IO 忽高忽低(比如 0 → 22000 → 0 → 8500)很常见,大概率是应用用了 buffered I/O + page cache 回写机制,不是异常
- 非 root 用户查不到 systemd 或内核线程,报 Permission denied 属正常权限限制,不是命令问题
进阶:结合 -r 同时看内存与 IO 关联性
有些数据库 IO 毛刺实际源于内存压力触发 swap 或 page reclaim,可一次性拉取双维度:
-
pidstat -d -r 2 -p "$(pgrep -f 'postgres.*-D')":每 2 秒输出一次 IO + 内存(RSS、%MEM) - 若 wkB/s 飙升同时 RSS 突降,可能是进程主动刷脏页或触发内核 writeback
- RSS 稳定但 rkB/s 持续高位,说明是真实业务读请求(如报表查询、逻辑备份)


















