跳至内容
25 望闻问切:监控体系与可观测诊断

第 25 章 望闻问切:监控体系与可观测诊断

“有监控”很容易,“知道发生了什么”很难。

一个看起来成熟的平台可能同时拥有:

26 个 PostgreSQL 仪表盘
3,000 多种指标名
数百条记录规则
几十条告警规则
集中日志
追踪后端
值班通知

事故发生时却仍然只能说:

CPU 高了
连接多了
复制慢了
面板红了

这些句子描述了现象,没有回答五个决定性问题:

  1. 用户旅程是否真的失败、变慢、读旧或产生错误结果?
  2. 这是首发症状、伴随现象,还是已经被证据支持的机制?
  3. 观察数据是零、尚未刷新、被重置、被采样,还是根本缺失?
  4. 哪个 owner 应采取什么首个安全动作
  5. 什么证据能够证明恢复,而不是仅仅“面板变绿”?

第 24 章先定义了服务、SLI、SLO、控制目标、缺失语义和告警治理。本章做下一步:

observation contract
  -> 指标、日志、事件和追踪
      -> PostgreSQL 原生统计与 SQL 基线
          -> Pigsty 采集、存储、规则、面板和通知
              -> 可行动告警
                  -> 有界诊断包
                      -> 合成规则与离线路由演练
                          -> 覆盖表、盲区与生产门禁

这条链的重点不是“多收集一些数据”,而是让每个结论都能说明:

question       想回答什么
source         哪个系统产生事实
semantics      值、窗口、标签、reset 和缺失是什么意思
cost           采集、查询和保留会付出什么代价
action         谁可以做什么
verification   怎样证明结论与恢复
boundary       什么仍然不知道

本章目标

完成本章后,你应当能够:

  1. 从用户、入口、数据库和主机四层组织观察问题;
  2. 区分症状信号、原因信号、控制信号与监控系统自身信号;
  3. 说明指标、日志、事件和追踪各自适合回答什么;
  4. 为 label cardinality、采样、保留和查询成本建立预算;
  5. 把“没有数据”区分为无流量、采集故障、查询错误、延迟与真实零值;
  6. 正确读取 pg_stat_activitypg_locks 与 wait event;
  7. 使用 pg_stat_databasepg_stat_iopg_stat_walpg_stat_checkpointerpg_stat_archiver
  8. 解释累计计数、瞬时状态、估算值和进度视图的不同时间语义;
  9. 区分 WAL distance、时间 lag 与 commit-correlated freshness;
  10. 观察 autovacuum、冻结年龄、dead tuple、对象增长和维护进度;
  11. 正确解释 pg_stat_statements 的聚合键、reset、deallocation 与权限;
  12. 解释为什么 normalized query text 仍不能随意进入证据;
  13. 为慢语句、锁等待、临时文件和错误日志设置有界政策;
  14. 评估 auto_explainANALYZE、timing、采样和参数泄露成本;
  15. 把第 24 章 SLO 合同变成 multiwindow、multi-burn-rate 规则;
  16. 区分 page、ticket、diagnostic 与 proposed test route;
  17. 为 alert 的 for、分组、抑制、恢复和缺失语义写测试;
  18. 防止 fast burn、slow burn 与预算工单形成重复风暴;
  19. 防止 metamonitoring 抑制独立用户症状或正确性告警;
  20. 理解 Pigsty v4 的 VictoriaMetrics、VictoriaLogs、VictoriaTraces、 VMAlert、Alertmanager、Grafana、pg_exporter 与 Vector;
  21. clsinsip、database 与 queryid 在不同粒度间下钻;
  22. 从仪表盘回到 PostgreSQL SQL、日志和主机事实复核;
  23. 自动保存有界、私密、可复验的诊断包;
  24. 区分首发症状、相关现象、候选机制与根因;
  25. 限制诊断查询的 timeout、并发、结果量和权限;
  26. 用隔离时间序列验证 pending、firing、recovery 与 missing;
  27. 用空 receiver 离线验证路由,不触碰真实 pager;
  28. 输出覆盖矩阵,诚实标出尚未实现的应用 SLI;
  29. 对当前沙箱给出“机制通过、生产待决”的可审计结论。

本章不做什么

本章不是一个“复制几十条 PromQL 就上线”的规则包,也不会:

  • 把当前沙箱阈值包装成所有生产环境的通用答案;
  • 修改在线 VMAlert、Alertmanager、Grafana 或 PostgreSQL;
  • 向在线 Alertmanager 提交合成告警;
  • 接入 webhook、邮件、短信、Slack 或真实 pager;
  • 运行 EXPLAIN ANALYZE、压测、统计 reset 或数据库故障注入;
  • 导出 query text、bind value、日志正文、client address 或凭据;
  • pg_up=1 证明订单服务可用;
  • pg_lag=0 证明 read-your-writes;
  • failed_count>0 直接证明归档仍在失败;
  • 用“当前无告警”证明通知链可达;
  • 用一次仪表盘相关性宣布 root cause;
  • 声称 pg36_shop 已经具有真实应用埋点。

实验使用 pg36_shop 这一 synthetic teaching service。应用层五种信号仍是刻意 保留的缺口:

request outcome counter
request duration histogram
commit-correlated freshness probe
domain reconciliation gauge
restore-evidence age gauge

缺口不是失败的写作,而是本章必须保留的事实。如果没有应用事件,平台不能从 数据库组件指标“推算”出一个看似完整的用户 SLO。

从监控到可观测诊断

监控回答已知问题

监控通常从一个已知条件出发:

if bad_ratio_1h > threshold
and bad_ratio_5m > threshold
for 2m
then page

它适合稳定、可计算、可自动执行的问题:

  • SLO 是否快速燃烧;
  • exporter 是否持续不可达;
  • 规则是否持续报错;
  • 恢复证据是否超过政策期限;
  • 容量预测是否进入评审窗口。

可观测诊断解释未知状态

诊断从“不知道为什么”出发,需要沿不同证据层缩小假设:

user latency burn
  -> entry queue or rejection?
      -> pool saturation or connection churn?
          -> PostgreSQL active wait or lock?
              -> queryid cost or plan drift?
                  -> storage, WAL, checkpoint, vacuum or host constraint?

可观测性不是一个产品名,也不是“拥有 logs + metrics + traces”自动获得的属性。 它要求系统输出足够的、语义明确的证据,让操作者能区分多个竞争解释。

诊断不等于根因

本章采用四层语言:

层次可以说什么例子
首发症状最早被可靠观察到的服务偏离availability fast burn 先触发
伴随现象与症状同窗出现pool queue、lock wait 同时升高
候选机制现象与某机制一致长事务可能阻止 vacuum 推进
根因证据机制被复现/独立证实,反例被排除,修复验证闭环释放特定锁后等待消失且合成路径恢复

“两条线一起升高”最多是相关性。要升级为根因,至少需要:

mechanism
independent corroboration or reproduction
falsification attempts
repair verification

四层问题,而不是四套孤岛面板

本章把信号按问题分为四层:

主要问题首选事实
用户旅程是否成功、及时、正确、足够新鲜eligible events、合成探针、domain reconciliation
入口请求在哪排队、被路由、重试或拒绝应用 edge、HAProxy、PgBouncer
数据库PG 状态能否解释症状activity、locks、I/O、WAL、maintenance、queryid
主机资源或基础设施是否构成约束CPU、memory、disk、network、clock

从下往上推断很危险:

CPU 90%
  therefore users are slow          # 不成立

one replica is down
  therefore service is unavailable  # 不成立

pg_up == 1
  therefore orders are correct       # 不成立

从上往下诊断更稳健:

user symptom is real
  -> locate affected operation and path
  -> correlate entry and database evidence
  -> test competing mechanisms
  -> choose the least harmful action
  -> verify user and control signals

正确性与恢复就绪又是特殊控制:

one unexplained cross-tenant row
  cannot be averaged away

old or missing restore evidence
  cannot be replaced by backup job success

四种信号,各有边界

信号擅长不擅长必须声明
metric趋势、比率、聚合、规则高维上下文、单请求故事type、unit、label、reset、missing
log离散事件、错误上下文、状态迁移完整总体比率、无界扫描schema、采样、脱敏、保留
event发布、切换、配置和所有权时间线单独证明因果actor、target、result、clock
trace单次跨组件路径未采样总体、长期预算sample、baggage、PII、correlation

四者不是竞争关系:

metric detects
event bounds the change window
trace follows one affected request
log explains a discrete failure
SQL verifies PostgreSQL state

同样,也不应强迫每个问题都使用四种信号。一个能够由累计计数精确回答的问题, 不需要先扫描全部日志;一个需要参数上下文的问题,也不应把 error text 做成 metric label。

时间语义比数值更重要

观察数据至少有五种时间性质:

类型示例典型陷阱
当前状态pg_stat_activity.state一次采样漏掉短暂事件
累计计数pg_stat_database.xact_commit把总数当速率、忽略 reset
滚动窗口rate(counter[5m])窗口过短、采样不足
估算值n_dead_tup当成精确 bloat
当前进度pg_stat_progress_vacuum没有行不等于从未运行

还要处理采集链延迟:

database state time
  -> exporter scrape time
      -> storage ingestion time
          -> rule evaluation time
              -> route grouping delay
                  -> receiver delivery time

如果数据源有意延迟 30 秒,而规则在“当前时刻”查询,最新样本可能尚未可见。 VMAlert 支持 evaluation delay;正确值取决于实际采集和存储延迟,不能机械照抄。

本章的规则分层

实验生成 18 条记录规则和 13 条告警规则。它们分成三类:

第 24 章已经接受的七条

告警路由目的
PG36ShopAvailabilityFastBurnpage1h + 5m,14.4x
PG36ShopAvailabilitySlowBurnpage6h + 30m,6x
PG36ShopAvailabilityBudgetTicketticket3d + 6h,1x
PG36ShopFreshnessFastBurnpagecommit-correlated freshness
PG36ShopCorrectnessMismatchpage不允许平均稀释的正确性
PG36ShopCapacityHorizonticket经评审预测才进入工作队列
PG36MonitoringPathBrokenpage观察或通知路径不可证明工作

仍待治理接受的六条

latency burn
restore evidence stale
active archive risk
long transaction horizon
freeze-age horizon
expected traffic but SLI missing

它们有完整规则和测试,但统一标记:

route: test
severity: candidate
governance_status: proposed-not-accepted

“代码写好了”不等于“组织接受了 page/ticket 政策”。这个显式不一致检查很重要: 第 24 章定义了 latency SLO,却没有接受 latency alert candidate。本章没有暗中 补齐生产政策,而是把它暴露为待决项。

诊断记录

复制距离、长事务、freeze age、dead tuples、exporter 状态、VMAlert rule error 和 notification failure 首先是诊断或控制输入。它们不会因为“容易写阈值”就 自动变成 page。

当前沙箱的真实快照

正式实验公共摘要: observability-run.json

采集时间为 2026-07-29T22:48:21Z。快照只代表该时刻:

项目观察值
Pigstyv4.4.0
PostgreSQL18.4
pg_exporterv1.4.0
VictoriaMetricsv1.148.0
VictoriaLogsv1.52.0
VictoriaTracesv0.9.4
Alertmanager0.33.1
VictoriaMetrics series44,842
live VMAlert groups17
live alert rules50
live recording rules698
live rule errors0
current VMAlert alerts0
pg_up / pg_exporter_up instances4 / 4
pg36_shop_* application SLI series0

目标身份通过三层交叉确认:

host            pg-test-1
Patroni scope   pg-test
PostgreSQL      cluster_name=pg-test
role            primary
replication     pg-test-2 + pg-test-3, async streaming
observed WAL gap 0 + 0 bytes

0 bytes 是当时的发送—回放距离,不是 read-your-writes 证明。

pg_stat_statements 快照:

extension version      1.12
schema                 monitor
rows                   194
calls                  122,303
query text exported    false
stats reset            retained

归档快照有一个关键反例:

failed_count           21
last failure           18:57:58Z
last successful archive 22:27:54Z

如果规则只是:

pg_archiver_failed_count > 0

它会在系统已经恢复后永久报警,直到统计被重置。候选规则因此同时检查:

15m 内出现新失败
AND 最近成功归档已经停滞

再回到 pgBackRest 与恢复证据复核。累计 counter、当前故障和恢复就绪是三个 不同结论。

实验为什么分成在线与隔离两部分

在线只读基线

在线部分只做:

  • HTTP health/API/metrics 读取;
  • VictoriaMetrics 即时查询;
  • 通过元节点进入真实 pg-test-1
  • statement_timeout=5slock_timeout=500ms 的只读 SQL;
  • 聚合 activity、locks、I/O、WAL、checkpointer、archiver、 replication 和 pg_stat_statements
  • 记录版本、reset、freshness 与缺口。

不会 reset、reload、写表、运行计划、制造负载或读取 query text。

隔离规则与路由

规则文件上传到沙箱元节点的:

/tmp/pg36-ch25.XXXXXXXX

随后:

  1. vmalert -dryRun 检查规则语法;
  2. vmalert-tool 启动 loopback-only VictoriaMetrics;
  3. 注入合成时间序列;
  4. 验证 normal、pending、firing、recovery 和 missing;
  5. amtool check-config 检查 Alertmanager 配置;
  6. 用八组标签离线解析到空 receiver;
  7. 用五个用例验证抑制边界;
  8. 清理临时目录并确认目录不存在。

它不会接触在线 VMAlert 或在线 Alertmanager。

本章目录

25.1 从问题选择可观测信号

25.2 PostgreSQL 核心运行信号

25.3 SQL 可观测基线

25.4 把观察契约变成告警

25.5 Pigsty 可观测体系

25.6 从告警到诊断包

25.7 实战:实现并演练观察契约

官方资料

本章技术语义优先回到原始文档:

下一章 第 26 章 容量规划与压测基线 会在这些观察 语义之上建立需求模型、容量水位和可比较基线;第 28 章 VACUUM、冻结与膨胀治理 再深入维护信号。第 31 章把本章的诊断包作为故障排查入口,处理慢查询、锁、 连接、复制与磁盘等具体事件。


上一章:纲举目张:SLO、SOP 与组织治理 · 返回下卷导读 · 下一章:胸有成竹:容量规划与压测基线 · 查看全书目录 · 查看索引中心

最后更新于