8.6 从可观测面板回到原生证据
Pigsty 的价值之一,是把 PostgreSQL、主机、连接池、代理、日志和 catalog 信息放进同一套时间与标签体系。面板擅长发现“何时、哪里、哪个查询族”异常;最终解释仍要能落回 exporter expression、PostgreSQL view、日志字段和计划 artifact。
8.6.1 用指标语义定位时间、实例与查询
从宽到窄浏览,而不是从某张“慢查询”表直接猜根因:
用户 SLI / 告警时间窗
→ cluster/service 是否整体异常
→ primary/replica/instance 差异
→ database/user/application/session
→ query family/queryid
→ wait/lock/plan/resource
→ 原生证据与受控实验在当前 Pigsty dashboard 分类中,可按问题选择入口:
| 问题 | 参考 dashboard 家族 | 要带走的身份 |
|---|---|---|
| 全局/cluster 是否退化 | PGSQL Overview、Alert、Cluster | cluster、instance、role、UTC window |
| session、负载、锁 | PGSQL Activity、Session、Xacts、PGCAT Locks | database、application、state/wait、PID/session |
| query family | PGSQL Query、PGCAT Query、Database | db/user/queryid、calls/time/rows |
| 代理与连接池 | PGSQL Service、Proxy、Pgbouncer | service route、pool/database/user |
| WAL/checkpoint/I/O | PGSQL Persist、Instance | instance timeline、counter/rate |
| 日志事件 | PGLOG Overview、Session | session/PID、SQLSTATE、timestamp |
这些名字是 Pigsty 的当前参考实现,不是永恒导航路径。若版本调整 dashboard,仍按“影响范围 → 实例 → 会话/query → 原生证据”的语义寻找。
打开任何图前,先读变量和 expression:
- 当前 cluster/service/instance/database/query 变量是什么;
- timezone 与 absolute start/end 是什么;
- unit 是 seconds、milliseconds、bytes、rows 还是 ratio;
- 原始 metric 是 counter、gauge 还是 histogram;
rate()/increase()窗口与 Grafana step 是多少;- label 是否在 recording rule 中被聚合掉;
- primary role/failover 前后 instance identity 是否变化;
No data表示 0、未抓取、权限不足还是 exporter 错误。
颜色是展示规则,不是 PostgreSQL 语义。同一个红色可能代表固定阈值、动态 baseline 或只是主题配置;同一个“QPS”可能是 query counter rate、transaction rate 或 application request rate。下结论前保存 panel query、变量、时间范围与 datasource。
一个可靠的面板收敛过程:
- 把用户事故窗口扩大到前后各一段,观察变化点;
- 用同星期/相近流量窗口做 baseline;
- 对比 primary/replica、受影响/未受影响实例;
- 找到 database/user/application/queryid,而非只看 cluster 总量;
- 同屏核对 calls/total/rows、wait/locks、CPU/I/O、pool queue;
- 保存 absolute UTC window 和 query identity;
- 用下一目的 SQL/log/plan 复核。
8.6.2 用 SQL、日志和计划复核面板判断
面板提示 Lock wait 后,原生复核应至少得到一条边:
SELECT
clock_timestamp() AT TIME ZONE 'UTC' AS captured_at_utc,
pid,
backend_start,
datname,
usename,
application_name,
state,
wait_event_type,
wait_event,
pg_blocking_pids(pid) AS blocking_pids,
xact_start,
query_start,
query_id
FROM pg_stat_activity
WHERE datname = :'database'
AND state <> 'idle'
ORDER BY xact_start NULLS LAST;面板提示某 query family 预算上升后,保存累计边界:
SELECT stats_reset
FROM pg_stat_statements_info;
SELECT
userid, dbid, queryid, calls,
total_exec_time, mean_exec_time, max_exec_time,
rows, shared_blks_hit, shared_blks_read,
temp_blks_written, wal_bytes,
query
FROM pg_stat_statements
WHERE dbid = (
SELECT oid FROM pg_database WHERE datname = :'database'
)
AND queryid = :'queryid'::bigint;若 panel 来自 Prometheus counter,优先导出事故窗口的 expression/result,而不是把当前累计 SQL 行与历史五分钟 rate 直接比较。记录:
datasource + expression
absolute UTC range + step
all template variables
returned labels
counter reset/failover boundary日志复核要能串到同一 session 或 query:
timestamp
PID + session id/backend_start
database/user/application/client
SQLSTATE
duration
query/queryid
lock/temp/auto_explain context计划复核则保存可机器比较的 JSON 与环境:
SELECT version();
SELECT name, setting, unit, source
FROM pg_settings
WHERE name IN (
'plan_cache_mode',
'work_mem',
'random_page_cost',
'effective_cache_size',
'track_io_timing',
'compute_query_id'
)
ORDER BY name;再在安全环境使用代表参数执行:
EXPLAIN (ANALYZE, BUFFERS, WAL, SETTINGS, SUMMARY, FORMAT JSON)
SELECT ...;如果生产语句正在 Lock/ClientWrite 等待,activity 与日志可能已经足够证明直接机制;不要为了补一张计划图冒险重跑。计划回答“executor 选择与处理了什么”,wait 回答“采样时为什么没前进”,两者互补。
面板提示“连接用满”也要回到边界:
- PostgreSQL session count 与 state;
- PgBouncer client/server active/waiting;
- application pool acquire duration;
- HAProxy backend/session;
- service route 与 primary role。
仅看到 PostgreSQL connections 接近上限,无法区分连接泄漏、长事务、pool 配太大、流量上升或 failover 重连风暴。
8.6.3 不把截图、颜色或当前点击路径当作知识
截图可以证明“当时有人看见某个画面”,却通常缺少:
- panel expression 与数据源;
- 变量值与隐藏 filters;
- absolute start/end、timezone 和 step;
- unit、legend 聚合与 null handling;
- dashboard/version/commit;
- 原始样本与可重算结果;
- query/session identity;
- 图外的对照与反证。
因此证据包的优先级应是:
1. 原始 SQL/CSV/JSON/log/Prometheus result
2. query/expression、变量、时间范围、版本与 source hash
3. 机器断言和人工解释
4. 截图作为定位/沟通附件可长期保留的知识应写成语义:
若 endpoint p99 退化:
先锁定 absolute UTC window 和 event count;
比较 cluster/instance/database/application/query scope;
若 activity 显示 active + Lock,保存 blocker edge;
若 active + ClientWrite 且 blockers 为空,转查结果消费;
若无稳定 wait,再进入 plan/CPU/I/O 假设;
所有结论回到原始 artifact。而不是:
打开左边第 3 个 dashboard,
点右上角红色方块,
再点第二行蓝色链接。前一种写法能跨 Pigsty/Grafana 版本、主题和自定义 dashboard;后一种在下一次升级就失效。需要记录当前实现时,附上:
Pigsty version
dashboard UID/title/revision
Grafana/Prometheus datasource
exporter and recording-rule source hash
PostgreSQL major/minor面板本身也需要验证。常见故障包括 exporter down、scrape timeout、label 重命名、recording rule 计算错误、queryid 类型/符号处理、counter reset 未处理和 dashboard variable 选错实例。若面板与原生 SQL 矛盾,先核对口径与时间,不要自动相信“更漂亮”的一方。
本章的方法把 Pigsty 定位为可观测性工作台:
Pigsty 快速收敛范围
+ PostgreSQL 证明机制
+ 应用/代理补全数据库外时间
+ 受控实验区分竞争解释
+ evidence bundle 供复核下一节把这条链放进三个外观相似、修复方向完全不同的可复现实验。
参考资料
- Pigsty:PostgreSQL Dashboards
- PostgreSQL 18:Cumulative Statistics System
- PostgreSQL 18:pg_stat_statements
上一节:设计受控实验 · 返回本章目录 · 下一节:实战:三种“慢”只修真正瓶颈 · 查看全书目录 · 查看索引中心