主动故障检测

主动故障检测(Patroni 存活,PG 宕机)场景下的 RTO 计算逻辑与结果分析

Pigsty 提供了四种 RTO 配置策略,下面是对三类故障场景下,不同 RTO 模式的最差,最优,平均 RTO 的计算逻辑与结果分析。


RTO 计算


主动检测

PG 崩溃场景(主动检测)RTO 对比

模式最好 RTO平均 RTO最坏 RTO
fast7s12s19s
norm18s23s31s
safe63s73s88s
wide127s158s198s

故障路径

注意:HAProxy 检测旧主 DOWN 与 Patroni 流程并行执行,在 promote 完成前早已完成,不计入 RTO

RTO 计算公式

RTO = loop_wait + primary_start_timeout + loop_wait + 选举 + HAProxy新主UP
    = 2 × loop_wait + primary_start_timeout + 选举 + HAProxy新主UP

RTO 构成分析

RTO = 2 × loop_wait + primary_start_timeout + 选举(~1s) + HAProxy新主UP
      \_________/   \__________________/
       可变成本           固定成本
  • 固定成本primary_start_timeout 是最大的固定成本,占 RTO 的 27%~96%
  • 可变成本:主要来自 2 × loop_wait(主库检测 + 从库检测),最坏情况两者都是满值
  • HAProxy 延迟:仅计算 rise × fastinter(新主上线检测),约 1~15s
  • HAProxy 旧主 DOWN:与 Patroni 流程并行执行,在 promote 完成前早已完成,不计入 RTO

与被动检测(节点宕机/网络分区)的差异:节点宕机时 Patroni 也死了,无法主动释放锁,只能等 TTL 过期被动触发。 而 PG 崩溃时 Patroni 还活着,会主动尝试恢复 PG,primary_start_timeout 决定了等待多久才放弃。


fast 模式

最好结果

参数: loop_wait=5, primary_start_timeout=5, inter=1s, fastinter=500ms, rise=2, fall=2

阶段操作耗时说明
1Patroni 检测到 PG 崩溃0sPG 恰好在 HA loop 检查时崩溃
2Patroni 尝试重启 PG5sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放0s从库恰好在 HA loop 检查点
5从库竞争 Leader 锁0sDCS 单次写操作
6执行 pg_ctl promote1sWAL 已同步,promote 快速完成
7HAProxy 检测新主 UP1srise=2 × fastinter=500ms
总计7s

最坏结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃5sPG 恰好在 HA loop 刚结束时崩溃
2Patroni 尝试重启 PG5sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放5s从库 HA loop 恰好错过
5从库竞争 Leader 锁1sDCS 操作 + 网络延迟
6执行 pg_ctl promote1spromote + 少量 WAL 回放
7HAProxy 检测新主 UP2srise=2 × inter=1s(从 DOWN 状态开始)
总计19s

平均结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃3sloop_wait/2
2Patroni 尝试重启 PG5sprimary_start_timeout 固定
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放3sloop_wait/2
5从库竞争 Leader 锁0sDCS 操作平均延迟
6执行 pg_ctl promote1spromote 平均时间
7HAProxy 检测新主 UP1srise=2 × fastinter
总计12s

小结

阶段操作最好平均最坏
1Patroni 检测到 PG 崩溃0s3s5s
2Patroni 尝试重启 PG5s5s5s
3释放 Leader 锁0s0s0s
4从库检测到 Leader 锁释放0s3s5s
5从库竞争 Leader 锁0s0s1s
6执行 pg_ctl promote1s1s1s
7HAProxy 检测新主 UP1s1s2s
总计7s12s19s

fast 模式下 PG 崩溃场景 RTO 范围为 7s ~ 19s,平均约 12sprimary_start_timeout=5s 是固定成本,两个 loop_wait 周期(0~10s)是主要变量。此配置适合同机房低延迟环境,能快速完成故障切换。


norm 模式

参数: loop_wait=5, primary_start_timeout=15, inter=2s, fastinter=1s, rise=2, fall=3

最好结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃0sPG 恰好在 HA loop 检查时崩溃
2Patroni 尝试重启 PG15sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放0s从库恰好在 HA loop 检查点
5从库竞争 Leader 锁0sDCS 单次写操作
6执行 pg_ctl promote1sWAL 已同步,promote 快速完成
7HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计18s

最坏结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃5sPG 恰好在 HA loop 刚结束时崩溃
2Patroni 尝试重启 PG15sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放5s从库 HA loop 恰好错过
5从库竞争 Leader 锁1sDCS 操作 + 网络延迟
6执行 pg_ctl promote1spromote + 少量 WAL 回放
7HAProxy 检测新主 UP4srise=2 × inter=2s(从 DOWN 状态开始)
总计31s

平均结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃3sloop_wait/2
2Patroni 尝试重启 PG15sprimary_start_timeout 固定
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放3sloop_wait/2
5从库竞争 Leader 锁0sDCS 操作平均延迟
6执行 pg_ctl promote1spromote 平均时间
7HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计23s

小结

阶段操作最好平均最坏
1Patroni 检测到 PG 崩溃0s3s5s
2Patroni 尝试重启 PG15s15s15s
3释放 Leader 锁0s0s0s
4从库检测到 Leader 锁释放0s3s5s
5从库竞争 Leader 锁0s0s1s
6执行 pg_ctl promote1s1s1s
7HAProxy 检测新主 UP2s2s4s
总计18s23s31s

norm 模式下 PG 崩溃场景 RTO 范围为 18s ~ 31s,平均约 23sprimary_start_timeout=15s 给了 PG 一定的本地恢复机会(如 crash recovery),同时保持了合理的 RTO。这是生产环境的推荐配置,平衡了故障恢复速度和误判风险。


safe 模式

参数: loop_wait=10, primary_start_timeout=60, inter=3s, fastinter=1s, rise=2, fall=3

最好结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃0sPG 恰好在 HA loop 检查时崩溃
2Patroni 尝试重启 PG60sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放0s从库恰好在 HA loop 检查点
5从库竞争 Leader 锁0sDCS 单次写操作
6执行 pg_ctl promote1sWAL 已同步,promote 快速完成
7HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计63s

最坏结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃10sPG 恰好在 HA loop 刚结束时崩溃
2Patroni 尝试重启 PG60sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放10s从库 HA loop 恰好错过
5从库竞争 Leader 锁1sDCS 操作 + 网络延迟
6执行 pg_ctl promote1spromote + 少量 WAL 回放
7HAProxy 检测新主 UP6srise=2 × inter=3s(从 DOWN 状态开始)
总计88s

平均结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃5sloop_wait/2
2Patroni 尝试重启 PG60sprimary_start_timeout 固定
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放5sloop_wait/2
5从库竞争 Leader 锁1sDCS 操作平均延迟
6执行 pg_ctl promote1spromote 平均时间
7HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计73s

小结

阶段操作最好平均最坏
1Patroni 检测到 PG 崩溃0s5s10s
2Patroni 尝试重启 PG60s60s60s
3释放 Leader 锁0s0s0s
4从库检测到 Leader 锁释放0s5s10s
5从库竞争 Leader 锁0s1s1s
6执行 pg_ctl promote1s1s1s
7HAProxy 检测新主 UP2s2s6s
总计63s73s88s

safe 模式下 PG 崩溃场景 RTO 范围为 63s ~ 88s,平均约 73sprimary_start_timeout=60s 给大型数据库充足的 crash recovery 时间,降低不必要的 failover。此配置适合数据安全性要求极高、可容忍分钟级中断的场景。


wide 模式

参数: loop_wait=30, primary_start_timeout=120, inter=5s, fastinter=2s, rise=3, fall=5

最好结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃0sPG 恰好在 HA loop 检查时崩溃
2Patroni 尝试重启 PG120sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放0s从库恰好在 HA loop 检查点
5从库竞争 Leader 锁1sDCS 单次写操作(广域网延迟)
6执行 pg_ctl promote1sWAL 已同步,promote 快速完成
7HAProxy 检测新主 UP6srise=3 × fastinter=2s
总计127s

最坏结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃30sPG 恰好在 HA loop 刚结束时崩溃
2Patroni 尝试重启 PG120sprimary_start_timeout 固定等待
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放30s从库 HA loop 恰好错过
5从库竞争 Leader 锁2sDCS 操作 + 广域网延迟
6执行 pg_ctl promote1spromote + 少量 WAL 回放
7HAProxy 检测新主 UP15srise=3 × inter=5s(从 DOWN 状态开始)
总计198s

平均结果

阶段操作耗时说明
1Patroni 检测到 PG 崩溃15sloop_wait/2
2Patroni 尝试重启 PG120sprimary_start_timeout 固定
3释放 Leader 锁0s超时后立即释放
4从库检测到 Leader 锁释放15sloop_wait/2
5从库竞争 Leader 锁1sDCS 操作平均延迟
6执行 pg_ctl promote1spromote 平均时间
7HAProxy 检测新主 UP6srise=3 × fastinter=2s
总计158s

小结

阶段操作最好平均最坏
1Patroni 检测到 PG 崩溃0s15s30s
2Patroni 尝试重启 PG120s120s120s
3释放 Leader 锁0s0s0s
4从库检测到 Leader 锁释放0s15s30s
5从库竞争 Leader 锁1s1s2s
6执行 pg_ctl promote1s1s1s
7HAProxy 检测新主 UP6s6s15s
总计127s158s198s

wide 模式下 PG 崩溃场景 RTO 范围为 127s ~ 198s(约 2~3 分钟),平均约 158s(约 3 分钟)。primary_start_timeout=120sloop_wait=30s 提供极强的容错能力,适合广域网/跨数据中心部署。此配置优先保证不误判,代价是故障切换时间较长。


被动探测

手动触发