34 过载保护与资源故障判型——李代桃僵
数据库“慢、满、连不上”时,最危险的动作往往不是没有动作,而是把正确手段用在了 错误根因上:
本章把资源事故分成两条首先必须分开的路径:
二者可以同时发生,也可能都不是。如果证据不足,正确路线不是猜一个,而是
STOP_AND_INVESTIGATE:停止破坏性清理、冻结新增变量、保留 SQL 与主机证据,并明确
尚未回答的问题。
学习完成标准
完成本章后,读者应能:
- 把“CPU 高、磁盘满、延迟高、连接失败”视为症状,而不是根因;
- 区分流量型竞争与 WAL/XID/slot/归档/长事务造成的保留型压力;
- 解释到达率、服务率、并发、队列和超时为什么会形成正反馈;
- 为应用池、PgBouncer、HAProxy 与 PostgreSQL 分配一致的连接预算;
- 识别健康检查、短连接和无抖动重试造成的隐藏放大;
- 用
pg_stat_activity、wait event、阻塞树和执行计划识别失控工作; - 区分
pg_cancel_backend与pg_terminate_backend的影响和权限边界; - 在结束长事务或大事务前评估锁释放、中止清理、既有 WAL、死版本与后续 vacuum 成本;
- 用并发最坏值估算
work_mem、并行 worker 与连接数的内存风险; - 将 PostgreSQL 的 I/O 证据与主机设备延迟、队列和文件系统余量互证;
- 为限流、熔断、摘流、取消和只读降级写出收益、代价、停止线与回退;
- 从
backend_xmin、复制槽xmin/catalog_xmin和 prepared transaction 判断 XID 保留者; - 从
restart_lsn、wal_status、归档与备份状态判断 WAL 保留者; - 解释为什么绝不能在运行中的实例里手工删除
pg_wal文件; - 用 Pigsty 的服务端点、连接池与监控缩小影响范围,但回到 PostgreSQL/OS 证据判型;
- 在不知道盲测答案时选择正确路线,并拒绝 34 类越界或误判证据。
一张判型表
| 问题 | 流量型 | 保留型 |
|---|---|---|
| 核心状态 | 到达工作超过可服务能力 | 最老的必需历史边界不能前进 |
| 典型信号 | 连接拒绝、队列、锁等待、CPU/I/O 饱和 | inactive slot、旧 xmin、归档失败、WAL 累积 |
| 第一目标 | 减少 admission、并发或单项成本 | 找到 owner 与恢复来源,保护 lineage |
| 可以立即做 | 限流、暂停批处理、精确 cancel、降级 | 留证、隔离增长、恢复消费者、评估精确释放 |
| 不应盲做 | 临时放大连接/内存,广域 terminate | cancel 普通查询、删 pg_wal、随意 drop slot |
| 成功证据 | 队列下降、拒绝停止、业务探针恢复 | 保留边界推进、归档/消费者恢复、恢复链完整 |
资源余量也不是一个百分比。至少要同时表达:
其中 $L_r$ 是资源 $r$ 的安全上限,$U_r$ 是当前与已承诺使用量。对连接、内存、WAL 空间、XID age、I/O 服务能力分别计算的 $H_r$ 不能相互替代。磁盘还有 30% 并不能 证明连接有余量;CPU 只有 20% 也不能证明 WAL 保留安全。
对流量型队列,若一段持续窗口内到达率 $\lambda$ 大于完成率 $\mu$:
队列 $Q$ 就会增长。平均值暂时正常也救不了尾延迟;重试还会反过来抬高 $\lambda$。 对保留型压力,真正需要测的是“最老仍被需要的位置”及其推进速度,而不是只看目录 当前大小。
事故时的四步闭环
每一步都要记录 UTC 时间、证据引用、操作者、预期收益、停止条件和实际结果。仅仅看到 面板曲线下降,不能说明动作正确:流量也可能因为所有客户端都超时而“下降”。
正式实验
本章在已确认的 Pigsty 开发沙箱做两层实验:
runner 用系统随机源安排两个 blind case,classifier 只能读取共同告警
postgresql-resource-headroom-at-risk 及观测字段,不能读取 hidden truth。正式顺序为:
正式观测:
| 情形 | 关键证据 | 判定与动作 |
|---|---|---|
| connection storm | 30 次尝试,21 个会话,9 次拒绝,20 个锁等待 | RELIEVE_FLOW_PRESSURE;精确 cancel fixture sessions |
| WAL retention | 1 个 inactive physical slot,保留 42,611,296 bytes | PRESERVE_RETENTION_EVIDENCE;先留证,再 drop exact disposable slot |
两个 case 完成后:
验证器同时构造并拒绝 34 个真实 mutant,包括生产边界被打开、blind packet 泄露答案、
阈值被削弱、广域 cancel、slot 仍残留以及谎报清理成功。公开证据见
overload-run.json。
这份实验能证明在该隔离 PG18 合同内两类证据可区分,且精确动作能复位 fixture。
它不证明生产连接上限、真实 OOM victim、文件系统填满行为、归档仓库故障或未知
replication slot 可以安全删除;最终门禁固定为 production_ch34_gate=pending。
阅读前后关系
本章目录
34.1 第一动作:流量型还是保留型
- 34.1.1 流量增长、慢查询、锁与连接导致的竞争
- 34.1.2 WAL、XID、复制槽、归档和长事务导致的保留
- 34.1.3 同样表现为“磁盘满”或“延迟高”,动作可以相反
- 34.1.4 判型不清时先停止破坏性清理
34.2 连接风暴与排队失控
34.3 失控查询、锁与事务
34.4 CPU、内存、I/O 与 OOM
34.5 流量型止血动作
34.6 保留型故障的安全路由
- 34.6.1 XID:检查
backend_xmin、复制槽xmin与pg_prepared_xacts - 34.6.2 WAL 撑盘:检查归档失败、复制槽和未完成备份
- 34.6.3 绝不手工删除
pg_wal;保护现场后转 ch21/ch28/ch35 - 34.6.4 本章的一般止血动作不构成保留型修复
34.7 平台级流量控制与证据
34.8 实战:同一症状、两种成因
- 34.8.1 随机注入连接风暴或 WAL 保留
- 34.8.2 在不知道答案时先判型,再选择动作
- 34.8.3 对流量型恢复服务,对保留型完成安全路由
- 34.8.4 输出动作时间线、误判代价与容量改进项
权威参考
PostgreSQL:
- Monitoring Database Activity
pg_stat_activityand cumulative statistics- System Administration Functions
pg_replication_slots- Resource Consumption
- Kernel Resources and Linux OOM
- Replication Configuration
Pigsty:
上一章:故障切换与集群重建——力挽狂澜 · 返回下卷导读 · 下一章:数据抢救与工程取证——起死回生 · 查看全书目录 · 查看索引中心