PostgreSQL 健康体检样例报告:17.11 测试库死元组 13.04% 标黄,pg_stat_statements 缺 preload 记 N/A
在 PostgreSQL 17.11 测试库跑配对体检:连接/idle in transaction、autovacuum/死元组、膨胀粗估、pg_stat_statements(未 preload 则标明)、复制槽/WAL、checkpoint(pg_stat_checkpointer)。绿/黄/红规则 + 完整样例报告(自造 events 100 万行)。附脚本、只读 SQL、CSV/Markdown。
PostgreSQL 17.11 测试库 pg_hc_lab(自造 events 100 万行,2026-10-27):连接 6/100(6%)→ 绿;UPDATE 15 万行后 n_dead_tup=150000、dead_pct=13.04%,heap 57MB→66MB → 黄;CREATE EXTENSION pg_stat_statements 后仍报 must be loaded via shared_preload_libraries → 慢查询 N/A;复制 0 槽 0 从库 → N/A;checkpoint num_timed=264 / num_requested=7 → 绿。总体黄。
适用对象
- 样例总体 YELLOW:死元组/膨胀为黄,连接与 checkpoint 为绿,慢查询与复制为 N/A。
- 事务里跑 pg_sleep 显示 active/PgSleep,不是 idle in transaction;真正的 idle in transaction 是 BEGIN 之后客户端不再发语句(wait_event=ClientRead)。
- PostgreSQL 17 的 checkpoint 计数在 pg_stat_checkpointer(num_timed/num_requested),再查旧 bgwriter 列名会报 column does not exist。
- pg_stat_statements 仅装扩展不够,shared_preload_libraries 为空时查询直接失败——体检材料要先确认 preload。
绿 / 黄 / 红(本样例口径)
总体取已评分维度最差色;N/A 不参与。正式 ¥499 体检仍输出 P0/P1/P2 + 证据编号,本页只演示自检形态。
| 维度 | 绿 | 黄 | 红 |
|---|---|---|---|
| 连接 / idle in tx | 占用 <70% 且无 idle in tx | 占用≥70% 或存在 idle in tx | 占用≥90% 或 idle in tx≥20 |
| autovacuum / 死元组 | autovacuum=on 且 dead%<10 | dead%≥10 | autovacuum 关或 dead%≥40 |
| 膨胀粗估 | 以 dead% 代理,同左 | 同左 | 同左 |
| 慢查询 pgss | max mean <1000ms | ≥1000ms | ≥5000ms;未 preload → N/A |
| 复制槽 / WAL | 无从库/槽 → N/A | 槽落后 | 槽失效/磁盘危急 |
| checkpoint | timed 为主 | req 明显高于 timed | 本样例不轻易标红 |
总体 YELLOW:死元组 13.04%
造数约 4.9 秒:100 万行,初始 total 95MB(heap 57 / index 37)。随后 UPDATE id≤150000:n_dead_tup=150000,dead_pct=13.04%,heap 涨到 66MB,total 108MB。autovacuum=on,但采集时死元组仍在——黄灯合理。
连接 6/100;复制 replicas=0、slots=0;wal_level=replica。checkpoint:num_timed=264,num_requested=7(PG17 视图 pg_stat_checkpointer)。
| 维度 | 关键数字 | 等级 |
|---|---|---|
| 连接 / idle in tx | 6/100(6%);可复现 idle in transaction | GREEN |
| autovacuum / 死元组 | dead_tup=150000;dead_pct=13.04% | YELLOW |
| 膨胀粗估 | heap 57→66MB;total 95→108MB | YELLOW |
| 慢查询 | pgss 缺 preload,不可用 | N/A |
| 复制槽 / WAL | 0 从库 0 槽 | N/A |
| checkpoint | timed=264,req=7 | GREEN |
| 总体 | 最差已评分 = 黄 | YELLOW |
SLEEP 不是 idle in transaction
第一次我在事务里 SELECT pg_sleep(8),快照里 state=active,wait_event_type=Timeout,wait_event=PgSleep。看起来「事务挂了很久」,但分类是错的。
改成:psql 长连接 BEGIN → SELECT COUNT(*) → 不再发语句。此时 state=idle in transaction,wait_event=ClientRead。这才是应用连接池泄漏、忘了 COMMIT 时常见的样子。
本机 idle_in_transaction_session_timeout=0(未启用)。样例连接维仍为绿,因为采集瞬间没有堆积;报告会注明「已复现、未形成连接占满」。生产若经常出现,应设超时并查应用。
扩展装着也不能查;checkpoint 换视图了
CREATE EXTENSION IF NOT EXISTS pg_stat_statements 返回成功,pg_extension 里看得到。一查就报:must be loaded via shared_preload_libraries。本机 SHOW shared_preload_libraries 为空。慢查询维只能 N/A,不能装绿。
替代:对两条语句做 EXPLAIN (ANALYZE, BUFFERS)。EXISTS 相关子查询 Execution Time 139.188 ms;按 user_id 聚合 Top20 为 48.132 ms。正式体检会要求先preload 再交 pgss 段,否则写「证据不足」。
PostgreSQL 17 把 checkpoint 统计拆到 pg_stat_checkpointer。再写 SELECT checkpoints_timed FROM pg_stat_bgwriter 会直接语法错。只读 SQL 已按 17 写好;老版本请改回 bgwriter。
脚本默认连 postgres 库;生产只用只读 SQL
lab 脚本默认 PSQL="psql -d postgres"(本机 peer);会 DROP/CREATE pg_hc_lab。DB 名必须以 _lab 结尾。
生产跑只读 SQL:连接、idle in transaction、死元组、体积、pgss(若可用)、槽/复制、checkpointer。把结果脱敏后可作体检材料。需要人审的备份恢复与权限项,仍走 ¥499 正式流程。
觉得有用?转给正在做这件事的同事或朋友
参考依据
以下来源用于确认市场趋势、政策背景和术语边界;具体落地方案仍以客户的数据范围、权限和交付目标为准。
常见问题
这份 PostgreSQL 体检样例总体是什么等级?
YELLOW。2026-10-27 在 PostgreSQL 17.11 测试库 pg_hc_lab:死元组 13.04% 与膨胀为黄,连接与 checkpoint 为绿,pg_stat_statements 与复制为 N/A。
为什么装了 pg_stat_statements 还是 N/A?
扩展在 catalog 里,但 shared_preload_libraries 为空,查询报 must be loaded via shared_preload_libraries。需要写入预加载并重启后再采。
idle in transaction 和事务内 SLEEP 有什么区别?
SLEEP 时 state=active(PgSleep);客户端停发语句时才是 idle in transaction(常见 ClientRead)。本次两种都复现过。
PostgreSQL 17 查 checkpoint 用哪张视图?
pg_stat_checkpointer(num_timed、num_requested 等)。pg_stat_bgwriter 只剩 buffers_clean 等清理相关列。
和 ¥499 体检、¥59 PG 学习包怎么配合?
本页是免费自检样例。学习包练慢查询/VACUUM/idle in tx 手法;体检把多维证据收成带等级的结果包并由人工复核关键项。
下一步
推荐动作
你提供只读巡检结果(可脱敏),我们在约定范围内标出连接、idle in transaction、死元组/膨胀、慢查询(若已 preload)、复制槽与 checkpoint 的风险与缺口;不对生产直接 VACUUM 或杀会话。