跳至内容
34 过载保护与资源故障判型——李代桃僵

第 34 章 过载保护与资源故障判型——李代桃僵

数据库“慢、满、连不上”时,最危险的动作往往不是没有动作,而是把正确手段用在了 错误根因上:

连接风暴  -> 扩大 max_connections  -> 内存与调度更快耗尽
WAL 撑盘 -> 取消慢查询              -> restart_lsn 一字节也不前进
XID 保留 -> 清理普通表空间          -> 冻结边界仍被旧 xmin 钉住
I/O 排队 -> 同时重启所有组件        -> 证据消失,恢复负载叠加

本章把资源事故分成两条首先必须分开的路径:

flow pressure
  新工作到达得比系统完成得快
  -> 排队、拒绝、超时、重试放大
  -> 目标是减少进入量、并发量或单项成本

retention pressure
  某个仍被声明为“需要”的历史边界不能前进
  -> WAL、旧版本或事务状态不能回收
  -> 目标是识别 owner、保护证据、修复消费者或恢复链

二者可以同时发生,也可能都不是。如果证据不足,正确路线不是猜一个,而是 STOP_AND_INVESTIGATE:停止破坏性清理、冻结新增变量、保留 SQL 与主机证据,并明确 尚未回答的问题。

学习完成标准

完成本章后,读者应能:

  1. 把“CPU 高、磁盘满、延迟高、连接失败”视为症状,而不是根因;
  2. 区分流量型竞争与 WAL/XID/slot/归档/长事务造成的保留型压力;
  3. 解释到达率、服务率、并发、队列和超时为什么会形成正反馈;
  4. 为应用池、PgBouncer、HAProxy 与 PostgreSQL 分配一致的连接预算;
  5. 识别健康检查、短连接和无抖动重试造成的隐藏放大;
  6. pg_stat_activity、wait event、阻塞树和执行计划识别失控工作;
  7. 区分 pg_cancel_backendpg_terminate_backend 的影响和权限边界;
  8. 在结束长事务或大事务前评估锁释放、回滚 WAL、I/O 与恢复时间;
  9. 用并发最坏值估算 work_mem、并行 worker 与连接数的内存风险;
  10. 将 PostgreSQL 的 I/O 证据与主机设备延迟、队列和文件系统余量互证;
  11. 为限流、熔断、摘流、取消和只读降级写出收益、代价、停止线与回退;
  12. backend_xmin、复制槽 xmin/catalog_xmin 和 prepared transaction 判断 XID 保留者;
  13. restart_lsnwal_status、归档与备份状态判断 WAL 保留者;
  14. 解释为什么绝不能在运行中的实例里手工删除 pg_wal 文件;
  15. 用 Pigsty 的服务端点、连接池与监控缩小影响范围,但回到 PostgreSQL/OS 证据判型;
  16. 在不知道盲测答案时选择正确路线,并拒绝 34 类越界或误判证据。

一张判型表

问题流量型保留型
核心状态到达工作超过可服务能力最老的必需历史边界不能前进
典型信号连接拒绝、队列、锁等待、CPU/I/O 饱和inactive slot、旧 xmin、归档失败、WAL 累积
第一目标减少 admission、并发或单项成本找到 owner 与恢复来源,保护 lineage
可以立即做限流、暂停批处理、精确 cancel、降级留证、隔离增长、恢复消费者、评估精确释放
不应盲做临时放大连接/内存,广域 terminatecancel 普通查询、删 pg_wal、随意 drop slot
成功证据队列下降、拒绝停止、业务探针恢复保留边界推进、归档/消费者恢复、恢复链完整

资源余量也不是一个百分比。至少要同时表达:

$$ H_r = L_r - U_r $$

其中 $L_r$ 是资源 $r$ 的安全上限,$U_r$ 是当前与已承诺使用量。对连接、内存、WAL 空间、XID age、I/O 服务能力分别计算的 $H_r$ 不能相互替代。磁盘还有 30% 并不能 证明连接有余量;CPU 只有 20% 也不能证明 WAL 保留安全。

对流量型队列,若一段持续窗口内到达率 $\lambda$ 大于完成率 $\mu$:

$$ \frac{dQ}{dt} \approx \lambda-\mu > 0 $$

队列 $Q$ 就会增长。平均值暂时正常也救不了尾延迟;重试还会反过来抬高 $\lambda$。 对保留型压力,真正需要测的是“最老仍被需要的位置”及其推进速度,而不是只看目录 当前大小。

事故时的四步闭环

1. bound
   影响哪个服务、角色、数据库、主机和时间窗?

2. classify
   flow、retention、both 还是 unknown?

3. relieve or route
   流量型做精确减压;保留型保护证据并进入专门恢复路径

4. verify
   用户探针、队列、保留边界、拓扑与临时动作是否全部复位?

每一步都要记录 UTC 时间、证据引用、操作者、预期收益、停止条件和实际结果。仅仅看到 面板曲线下降,不能说明动作正确:流量也可能因为所有客户端都超时而“下降”。

正式实验

本章在已确认的 Pigsty 开发沙箱做两层实验:

managed pg-test
  Patroni / SQL read-only capture before and after
  no connection storm, slot, cancel, service or route mutation

pg-test-3 disposable PostgreSQL 18.4
  /tmp/pg36-ch34-overload-<run-id>
  listen_addresses=''
  private Unix socket
  max_connections=24
  exact cleanup after server stop

runner 用系统随机源安排两个 blind case,classifier 只能读取共同告警 postgresql-resource-headroom-at-risk 及观测字段,不能读取 hidden truth。正式顺序为:

RETENTION -> FLOW

正式观测:

情形关键证据判定与动作
connection storm30 次尝试,21 个会话,9 次拒绝,20 个锁等待RELIEVE_FLOW_PRESSURE;精确 cancel fixture sessions
WAL retention1 个 inactive physical slot,保留 42,611,296 bytesPRESERVE_RETENTION_EVIDENCE;先留证,再 drop exact disposable slot

两个 case 完成后:

fixture sessions                   0
disposable physical slots          0
manual pg_wal file deletion    false
OOM / filesystem fill          false
managed topology changed       false
managed system id changed      false
managed timeline changed       false
exact temporary root remains   false

验证器同时构造并拒绝 34 个真实 mutant,包括生产边界被打开、blind packet 泄露答案、 阈值被削弱、广域 cancel、slot 仍残留以及谎报清理成功。公开证据见 overload-run.json

这份实验能证明在该隔离 PG18 合同内两类证据可区分,且精确动作能复位 fixture。 它不证明生产连接上限、真实 OOM victim、文件系统填满行为、归档仓库故障或未知 replication slot 可以安全删除;最终门禁固定为 production_ch34_gate=pending

所属位置

本章目录

34.1 第一动作:流量型还是保留型

34.2 连接风暴与排队失控

34.3 失控查询、锁与事务

34.4 CPU、内存、I/O 与 OOM

34.5 流量型止血动作

34.6 保留型故障的安全路由

34.7 平台级流量控制与证据

34.8 实战:同一症状、两种成因

权威参考

PostgreSQL:

Pigsty:


上一章:故障切换与集群重建——力挽狂澜 · 返回下卷导读 · 下一章:数据抢救与工程取证——起死回生 · 查看全书目录 · 查看索引中心

最后更新于