人工故障切换

人工触发 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 等待 这两个最大的时间消耗。