复制与高可用
PostgreSQL 的高可用 = 复制(热备)+ 自动故障转移(Patroni)+ 备份(PITR 兜底)。三种机制各管一段:物理复制管高可用,逻辑复制管异构同步,WAL 归档管恢复。
流复制(物理复制)
流复制
- 复制单位是 WAL 字节流,整个实例级复制,版本必须一致
- 异步(默认):主库提交不等备库,可能丢最近事务
- 同步:主库等备库确认(
synchronous_commit),保证不丢已提交事务,代价是提交延迟;生产同步模式至少三个节点,防止单备库故障卡死写入 - 复制延迟监控:
pg_stat_replication
逻辑复制
- 从 WAL 逻辑解码出行级变更(pgoutput 插件),表级选择性复制
- 支持跨大版本、异构目标(PG 12 到 17、同步到数仓)
- 发布/订阅模型(Publication/Subscription)
- 限制:不复制 DDL(要手动同步)、序列值不复制、冲突需要处理
典型组合:物理复制维护高可用集群,备库上再起逻辑复制把特定表同步到分析系统,两全其美。
Patroni:自动故障转移
PostgreSQL 原生不支持自动选主(主库挂了要手动 promote),Patroni 解决这个问题:
- etcd 存集群状态:谁是主、谁是备、当前配置
- leader 锁:主库通过 etcd 租约持有领导权,TTL 内未续租触发选举
- 健康检查 + 自动 promote:主库故障,候选备库按 LSN 进度竞选新主
- 防脑裂:旧主恢复后通过 pg_rewind 回卷重新加入,不双主
- 搭配 HAProxy:应用连 VIP,健康检查自动切换流量
生产指标:异步模式 RPO 可能丢最近事务,同步模式 RPO=0;RTO 常规配置 30 到 45 秒。典型架构是 Patroni(3 节点)+ etcd(3 节点)+ HAProxy。
备份与 PITR
| 方式 | 内容 | 用途 |
|---|---|---|
| pg_dump | 逻辑备份 SQL | 单库、跨版本迁移 |
| pg_basebackup | 物理基础备份 | 备库初始化、冷备 |
| WAL 归档 | 持续归档日志 | PITR 恢复 |
基础备份 + WAL 归档 = 恢复到任意时间点。高可用挡硬件故障,PITR 挡误删和逻辑错误,两者都要。
面试追问
- 流复制和逻辑复制的区别? 物理复制复制 WAL 字节流、实例级、版本必须一致;逻辑复制解码行级变更、表级可选、支持跨版本
- 同步复制怎么保证不丢数据? 主库等备库确认 WAL 落盘才返回成功。代价是提交延迟,生产至少三节点
- Patroni 怎么选主? etcd 存状态,leader 租约超时触发选举,备库按 LSN 进度竞选。旧主用 pg_rewind 回卷防脑裂
- 逻辑复制不复制什么? DDL 和序列值,要手动同步。冲突会停复制,需处理
- RPO 和 RTO 怎么权衡? 异步 RPO 大于零但写入快,同步 RPO=0 但提交延迟。RTO 常规 30 到 45 秒