这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

故障时序模型

详细分析三种经典故障检测/恢复路径下,最差,最优,平均 RTO 的计算逻辑与结果

在 Patroni 中,根据故障检测的机制,有三条典型的 RTO 计算路径,本节将分情况讨论。

检测机制检测主体检测信号典型故障主要来源
被动检测DCS (etcd)leader key TTL 到期网络分区,节点崩溃,Patroni 宕机ttl
主动探测Patroni 领导者pg_isready 失败PG 进程崩溃priamry_start_timeout
手动触发运维人员patronictl switchover/failover主动切换命令,维护操作haproxy_up

检测到故障之后,恢复过程的 RTO 还需要包括恢复策略的耗时,以及 HAProxy 健康检查的耗时。

1 - 被动故障检测

被动故障检测(节点宕机,网络分区)场景下的 RTO 时序分析

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

被动检测

节点宕机/网络分区场景(被动检测)RTO 对比

模式最好 RTO平均 RTO最坏 RTOTTL 占比
fast17s22s29s80%
norm28s33s41s83%
safe53s63s78s87%
wide97s128s168s82%

故障路径

RTO 计算公式

RTO = TTL等待 + 从库检测 + 竞争锁 + promote + HAProxy_UP
    = (ttl - loop_wait ~ ttl) + (0 ~ loop_wait) + 选举 + HAProxy_UP

RTO 构成分析

RTO = TTL等待 + loop_wait + 选举(~1s) + HAProxy_UP
      \_____/   \______/
      主要固定成本  可变成本
  • 固定成本:TTL 等待是最大成本(占 80%~87%),这是被动检测的本质代价
  • 可变成本:从库检测延迟(0 ~ loop_wait)
  • HAProxy 延迟:仅计算 rise × fastinter(UP 检测),DOWN 检测与选举并行,不在关键路径

TTL 等待时间的精确计算

Patroni Leader 每 loop_wait 续约一次,将 TTL 重置为完整值。当节点宕机时:

  续约周期示意图:
  
  ──────────────────────────────────────────────────────────────→ 时间
     │                    │                    │
   续约                  续约                  续约
   TTL=ttl              TTL=ttl              TTL=ttl
     │←── loop_wait ───→│
     
  如果故障发生在 Δt 处(续约后 Δt 时间):
  TTL 剩余 = ttl - Δt
  由于 Δt ∈ [0, loop_wait)
  所以 TTL 等待 ∈ (ttl - loop_wait, ttl]

与主动检测(PG 崩溃)的关键差异

对比项主动检测(PG 崩溃)被动检测(节点宕机)
主要控制参数primary_start_timeoutttl
Patroni 状态存活,主动处理失效,无法响应
锁释放方式主动释放自然过期
RTO 公式核心2×loop_wait + primary_start_timeout(ttl-loop_wait~ttl) + loop_wait

fast 模式

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

最好结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期15sttl - loop_wait = 20 - 5(故障恰好在续约前)
3从库检测到 Leader 锁过期0s从库恰好在 HA loop 检查点
4从库竞争 Leader 锁0.1sDCS 单次写操作
5执行 pg_ctl promote0.5sWAL 已同步,promote 快速完成
6HAProxy 检测新主 UP1srise=2 × fastinter=500ms
总计17s

最坏结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期20s完整 ttl = 20(故障恰好在刚续约后)
3从库检测到 Leader 锁过期5s从库 HA loop 恰好错过,等待下一轮
4从库竞争 Leader 锁0.5sDCS 操作 + 网络延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP2srise=2 × inter=1s(从 DOWN 状态开始)
总计29s

平均结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期18sttl - loop_wait/2 = 20 - 2.5
3从库检测到 Leader 锁过期2.5sloop_wait/2
4从库竞争 Leader 锁0.3sDCS 操作平均延迟
5执行 pg_ctl promote0.7spromote 平均时间
6HAProxy 检测新主 UP1srise=2 × fastinter
总计22s

小结

阶段操作最好平均最坏
1节点宕机,停止续约0s0s0s
2等待 TTL 过期15s18s20s
3从库检测到 Leader 锁过期0s2.5s5s
4从库竞争 Leader 锁0.1s0.3s0.5s
5执行 pg_ctl promote0.5s0.7s1s
6HAProxy 检测新主 UP1s1s2s
总计17s22s29s

fast 模式下节点宕机场景 RTO 范围为 17s ~ 29s,平均约 22s。TTL=20s 是主要耗时(占 80%),由于 loop_wait=5s 的续约频率,实际 TTL 等待范围被压缩到 15~20s。此配置适合同机房低延迟环境,追求最快的被动故障恢复。


norm 模式

参数: ttl=30, loop_wait=5, inter=2s, fastinter=1s, rise=2, fall=3

最好结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期25sttl - loop_wait = 30 - 5(故障恰好在续约前)
3从库检测到 Leader 锁过期0s从库恰好在 HA loop 检查点
4从库竞争 Leader 锁0.1sDCS 单次写操作
5执行 pg_ctl promote0.5sWAL 已同步,promote 快速完成
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计28s

最坏结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期30s完整 ttl = 30(故障恰好在刚续约后)
3从库检测到 Leader 锁过期5s从库 HA loop 恰好错过,等待下一轮
4从库竞争 Leader 锁0.5sDCS 操作 + 网络延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP4srise=2 × inter=2s(从 DOWN 状态开始)
总计41s

平均结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期28sttl - loop_wait/2 = 30 - 2.5
3从库检测到 Leader 锁过期2.5sloop_wait/2
4从库竞争 Leader 锁0.3sDCS 操作平均延迟
5执行 pg_ctl promote0.7spromote 平均时间
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计33s

小结

阶段操作最好平均最坏
1节点宕机,停止续约0s0s0s
2等待 TTL 过期25s28s30s
3从库检测到 Leader 锁过期0s2.5s5s
4从库竞争 Leader 锁0.1s0.3s0.5s
5执行 pg_ctl promote0.5s0.7s1s
6HAProxy 检测新主 UP2s2s4s
总计28s33s41s

norm 模式下节点宕机场景 RTO 范围为 28s ~ 41s,平均约 33s。TTL=30s 是主要耗时因素(占 83%)。这是生产环境的平衡选择,在故障恢复速度和集群稳定性之间取得折中。


safe 模式

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

最好结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期50sttl - loop_wait = 60 - 10(故障恰好在续约前)
3从库检测到 Leader 锁过期0s从库恰好在 HA loop 检查点
4从库竞争 Leader 锁0.2sDCS 单次写操作
5执行 pg_ctl promote0.5sWAL 已同步,promote 快速完成
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计53s

最坏结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期60s完整 ttl = 60(故障恰好在刚续约后)
3从库检测到 Leader 锁过期10s从库 HA loop 恰好错过,等待下一轮
4从库竞争 Leader 锁1sDCS 操作 + 网络延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP6srise=2 × inter=3s(从 DOWN 状态开始)
总计78s

平均结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期55sttl - loop_wait/2 = 60 - 5
3从库检测到 Leader 锁过期5sloop_wait/2
4从库竞争 Leader 锁0.5sDCS 操作平均延迟
5执行 pg_ctl promote0.7spromote 平均时间
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计63s

小结

阶段操作最好平均最坏
1节点宕机,停止续约0s0s0s
2等待 TTL 过期50s55s60s
3从库检测到 Leader 锁过期0s5s10s
4从库竞争 Leader 锁0.2s0.5s1s
5执行 pg_ctl promote0.5s0.7s1s
6HAProxy 检测新主 UP2s2s6s
总计53s63s78s

safe 模式下节点宕机场景 RTO 范围为 53s ~ 78s,平均约 63s。TTL=60s 提供了充足的容错窗口(占 87%),能有效避免短暂网络抖动导致的误判。此配置适合对稳定性要求极高、可容忍分钟级中断的场景。


wide 模式

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

最好结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期90sttl - loop_wait = 120 - 30(故障恰好在续约前)
3从库检测到 Leader 锁过期0s从库恰好在 HA loop 检查点
4从库竞争 Leader 锁0.5sDCS 单次写操作(广域网延迟)
5执行 pg_ctl promote0.5sWAL 已同步,promote 快速完成
6HAProxy 检测新主 UP6srise=3 × fastinter=2s
总计97s

最坏结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期120s完整 ttl = 120(故障恰好在刚续约后)
3从库检测到 Leader 锁过期30s从库 HA loop 恰好错过,等待下一轮
4从库竞争 Leader 锁2sDCS 操作 + 广域网延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP15srise=3 × inter=5s(从 DOWN 状态开始)
总计168s

平均结果

阶段操作耗时说明
1节点宕机,停止续约0sPatroni + PG 同时失效
2等待 TTL 过期105sttl - loop_wait/2 = 120 - 15
3从库检测到 Leader 锁过期15sloop_wait/2
4从库竞争 Leader 锁1sDCS 操作平均延迟
5执行 pg_ctl promote0.7spromote 平均时间
6HAProxy 检测新主 UP6srise=3 × fastinter=2s
总计128s

小结

阶段操作最好平均最坏
1节点宕机,停止续约0s0s0s
2等待 TTL 过期90s105s120s
3从库检测到 Leader 锁过期0s15s30s
4从库竞争 Leader 锁0.5s1s2s
5执行 pg_ctl promote0.5s0.7s1s
6HAProxy 检测新主 UP6s6s15s
总计97s128s168s

wide 模式下节点宕机场景 RTO 范围为 97s ~ 168s(约 1.6~2.8 分钟),平均约 128s(约 2.1 分钟)。TTL=120s 和 loop_wait=30s 提供极强的容错能力(TTL 占 82%),适合广域网/跨数据中心部署。此配置优先保证不误判,代价是故障切换时间较长。

2 - 主动故障检测

主动故障检测(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 提供极强的容错能力,适合广域网/跨数据中心部署。此配置优先保证不误判,代价是故障切换时间较长。


被动探测

手动触发

3 - 人工故障切换

人工触发 Failover / Switchover 下的的 RTO 计算逻辑与结果分析。

Switchover / Failover 场景(人工触发)RTO 对比

模式Switchover 平均Switchover 最坏Failover 平均Failover 最坏
fast2s5s2s4s
norm4s8s3s6s
safe4s10s3s8s
wide9s21s9s17s

Switchover(计划内优雅切换)

故障路径

准备阶段(老主库仍可用,不计入 RTO):

RTO 计时阶段(服务不可用):

RTO 计算公式

RTO = WAL追平 + 锁切换 + promote + HAProxy_UP

RTO 构成分析

RTO = WAL追平 + 锁释放(~0.3s) + 锁获取(~0.2s) + promote(~0.5s) + HAProxy_UP
      \______/
      同步复制时为0
  • WAL 追平:同步复制模式下为 0(已实时同步);异步复制时取决于复制延迟
  • 锁切换:DCS 两次原子操作(释放 + 获取),约 0.3~1s
  • HAProxy 延迟rise × fastinter

与 Failover 的差异

对比项SwitchoverFailover
WAL 追平✅ 等待(保证数据完整)❌ 跳过(可能丢数据)
其他阶段相同相同

fast 模式

参数: inter=1s, fastinter=500ms, rise=2

最好结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平0s同步复制,已完全同步
3主库释放 Leader 锁0sDCS 原子操作
4目标从库获取 Leader 锁0sDCS 原子操作
5执行 pg_ctl promote1spromote 快速完成
6HAProxy 检测新主 UP1srise=2 × fastinter=500ms
总计2s

最坏结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平1s异步复制,存在少量延迟
3主库释放 Leader 锁1sDCS 操作 + 网络延迟
4目标从库获取 Leader 锁1sDCS 操作 + 网络延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP2srise=2 × inter=1s(从DOWN开始)
总计5s

平均结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平0s少量复制延迟
3主库释放 Leader 锁0sDCS 原子操作
4目标从库获取 Leader 锁0sDCS 原子操作
5执行 pg_ctl promote1spromote 平均时间
6HAProxy 检测新主 UP1srise=2 × fastinter
总计2s

小结

阶段操作最好平均最坏
1主库停止接受写入0s0s0s
2等待从库 WAL 追平0s0s1s
3主库释放 Leader 锁0s0s1s
4目标从库获取 Leader 锁0s0s1s
5执行 pg_ctl promote1s1s1s
6HAProxy 检测新主 UP1s1s2s
总计2s2s5s

norm 模式

参数: inter=2s, fastinter=1s, rise=2

最好结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平0s同步复制,已完全同步
3主库释放 Leader 锁0sDCS 原子操作
4目标从库获取 Leader 锁0sDCS 原子操作
5执行 pg_ctl promote1spromote 快速完成
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计3s

最坏结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平2s异步复制,存在复制延迟
3主库释放 Leader 锁1sDCS 操作 + 网络延迟
4目标从库获取 Leader 锁1sDCS 操作 + 网络延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP4srise=2 × inter=2s(从DOWN开始)
总计8s

平均结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平1s少量复制延迟
3主库释放 Leader 锁0sDCS 原子操作
4目标从库获取 Leader 锁0sDCS 原子操作
5执行 pg_ctl promote1spromote 平均时间
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计4s

小结

阶段操作最好平均最坏
1主库停止接受写入0s0s0s
2等待从库 WAL 追平0s1s2s
3主库释放 Leader 锁0s0s1s
4目标从库获取 Leader 锁0s0s1s
5执行 pg_ctl promote1s1s1s
6HAProxy 检测新主 UP2s2s4s
总计3s4s8s

safe 模式

参数: inter=3s, fastinter=1s, rise=2

最好结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平0s同步复制,已完全同步
3主库释放 Leader 锁0sDCS 原子操作
4目标从库获取 Leader 锁0sDCS 原子操作
5执行 pg_ctl promote1spromote 快速完成
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计3s

最坏结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平2s异步复制,存在复制延迟
3主库释放 Leader 锁1sDCS 操作 + 网络延迟
4目标从库获取 Leader 锁1sDCS 操作 + 网络延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP6srise=2 × inter=3s(从DOWN开始)
总计10s

平均结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平1s少量复制延迟
3主库释放 Leader 锁0sDCS 原子操作
4目标从库获取 Leader 锁0sDCS 原子操作
5执行 pg_ctl promote1spromote 平均时间
6HAProxy 检测新主 UP2srise=2 × fastinter=1s
总计4s

小结

阶段操作最好平均最坏
1主库停止接受写入0s0s0s
2等待从库 WAL 追平0s1s2s
3主库释放 Leader 锁0s0s1s
4目标从库获取 Leader 锁0s0s1s
5执行 pg_ctl promote1s1s1s
6HAProxy 检测新主 UP2s2s6s
总计3s4s10s

wide 模式

参数: inter=5s, fastinter=2s, rise=3

最好结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平0s同步复制,已完全同步
3主库释放 Leader 锁1sDCS 原子操作(广域网延迟)
4目标从库获取 Leader 锁1sDCS 原子操作(广域网延迟)
5执行 pg_ctl promote1spromote 快速完成
6HAProxy 检测新主 UP6srise=3 × fastinter=2s
总计8s

最坏结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平3s异步复制 + 广域网复制延迟
3主库释放 Leader 锁2sDCS 操作 + 广域网延迟
4目标从库获取 Leader 锁1sDCS 操作 + 广域网延迟
5执行 pg_ctl promote1spromote + 少量 WAL 回放
6HAProxy 检测新主 UP15srise=3 × inter=5s(从DOWN开始)
总计21s

平均结果

阶段操作耗时说明
1主库停止接受写入0s即时生效
2等待从库 WAL 追平1s广域网复制延迟
3主库释放 Leader 锁1sDCS 原子操作(广域网延迟)
4目标从库获取 Leader 锁1sDCS 原子操作(广域网延迟)
5执行 pg_ctl promote1spromote 平均时间
6HAProxy 检测新主 UP6srise=3 × fastinter=2s
总计9s

小结

阶段操作最好平均最坏
1主库停止接受写入0s0s0s
2等待从库 WAL 追平0s1s3s
3主库释放 Leader 锁1s1s2s
4目标从库获取 Leader 锁1s1s1s
5执行 pg_ctl promote1s1s1s
6HAProxy 检测新主 UP6s6s15s
总计8s9s21s

Failover(强制切换)

故障路径

RTO 计算公式

RTO = 验证 + 获取锁 + promote + HAProxy_UP

说明:Failover 通常在主库已故障时使用,此时 RTO 从执行命令开始计时(主库已不可用)。


fast 模式

阶段操作最好平均最坏
1验证候选从库0s0s1s
2候选从库获取 Leader 锁0s0s1s
3执行 pg_ctl promote1s1s1s
4HAProxy 检测新主 UP1s1s2s
总计2s2s4s

norm 模式

阶段操作最好平均最坏
1验证候选从库0s0s1s
2候选从库获取 Leader 锁0s0s1s
3执行 pg_ctl promote1s1s1s
4HAProxy 检测新主 UP2s2s4s
总计3s3s6s

safe 模式

阶段操作最好平均最坏
1验证候选从库0s0s1s
2候选从库获取 Leader 锁0s0s1s
3执行 pg_ctl promote1s1s1s
4HAProxy 检测新主 UP2s2s6s
总计3s3s8s

wide 模式

阶段操作最好平均最坏
1验证候选从库1s1s1s
2候选从库获取 Leader 锁1s1s2s
3执行 pg_ctl promote1s1s1s
4HAProxy 检测新主 UP6s6s15s
总计8s9s17s

人工触发汇总

Switchover vs Failover 对比

模式SwitchoverFailover
最好平均最坏最好平均最坏
fast2s2s5s2s2s4s
norm3s4s8s3s3s6s
safe3s4s10s3s3s8s
wide8s9s21s8s9s17s

关键洞察

  1. Switchover 与 Failover RTO 非常接近
    • 差异仅在于 WAL 追平时间(同步复制时为 0)
    • 同步复制模式下,两者 RTO 几乎相同
  2. HAProxy 检测是主要延迟来源
    • 在人工触发场景中,HAProxy UP 检测占总 RTO 的 43%~65%
    • wide 模式下 HAProxy 延迟更为显著
  3. 与自动故障检测的对比
模式人工 Switchover人工 Failover主动检测(PG崩溃)被动检测(节点宕机)
fast2s2s12s13s
norm4s3s23s24s
safe4s3s73s73s
wide9s9s158s128s

人工触发比自动检测快 6~20 倍,因为跳过了 primary_start_timeoutTTL 等待 这两个最大的时间消耗。