这是一个非常关键、但很多资料都混着讲的问题。一句话先给结论:
PostgreSQL 流复制 ≠ 高可用
流复制只解决"数据同步"
高可用解决"主库挂了,业务还能继续写"
下面从概念、能力边界、故障场景、架构层次四个维度把区别讲透。
一、本质区别
| 项目 | PostgreSQL 流复制 | PostgreSQL 高可用 |
|---|---|---|
| 本质 | 数据复制技术 | 系统架构能力 |
| 解决什么 | 备库和主库数据一致 | 主库故障后业务不中断 |
| 是否原生 | ✅ PostgreSQL 自带 | ❌ 需要额外组件 |
| 是否自动 | ❌ 默认不自动 | ✅ 必须自动 |
| 是否防脑裂 | ❌ 不管 | ✅ 必须管 |
二、流复制到底是什么?
2.1流复制只做一件事
把主库的 WAL(物理变更日志)实时传到备库,备库重放,保持数据一致。
它只负责:
- 主库写 WAL
- walsender 发给备库
- walreceiver 接收
- startup 进程重放
- 备库数据 ≈ 主库数据
✅ 数据同步
❌ 不决定谁是主
❌ 不自动切换
❌ 不防止两个主
2.2流复制的典型状态
html
主库 10.0.0.18 正常运行
备库 10.0.0.28 streaming
此时:
- 备库 不能写
- 主库挂了,备库 不会自动升主
- 应用 不会自动连备库
如果你什么都不做:
主库宕机 = 业务中断
2.3流复制的"能力边界"
| 能做的 | 不能做的 |
|---|---|
| 异步 / 同步复制 | 自动选主 |
| 只读备库 | 防止脑裂 |
| 复制槽防 WAL 丢失 | 客户端自动路由 |
| 级联复制 | 故障检测 |
| 时间线管理 | 老主自动 rewind |
三、高可用到底是什么?
3.1高可用的定义
当主库不可用时,系统能在可接受时间内,自动把备库提升为新主,并让应用继续访问数据库。
关键词:
- ✅ 自动
- ✅ 可接受的 downtime(秒级)
- ✅ 数据不丢(或可控丢失)
- ✅ 不出现两个主(防脑裂)
3.2高可用必须解决的 5 个问题
① 故障检测
- 主库是真挂了?
- 还是网络抖动?
- 多久算故障?
② 选主(Leader Election)
- 多个备库中,谁升主?
- 依据:LSN 最新?优先级?权重?
③ 自动切换
- 执行
pg_promote() - 切时间线
- 更新集群状态
④ 防脑裂(Split-Brain)
- 网络分区时不能出现两个主
- 需要 多数派投票
⑤ 客户端路由
- 应用怎么知道新主是谁?
- VIP / DNS / Proxy / Driver-aware
四、为什么"流复制 + 手动 promote"不是高可用?
场景:主库宕机
html
10.0.0.18 主库宕机
只有流复制时
你需要:
- 人发现主库挂了
- 登录 28
- 执行
pg_promote() - 改应用连接串
- 重启应用或等连接超时
结果:
- ❌ 人工介入
- ❌ 分钟级甚至更长
- ❌ 容易误操作
- ❌ 脑裂风险
这是"灾备",不是高可用
五、高可用 = 流复制 + 控制平面
正确关系图
html
┌────────────────────────────┐
│ 高可用系统 │
│ │
│ ┌──────────────────────┐ │
│ │ 控制平面(HA) │ │
│ │ Patroni / repmgr │ │
│ │ etcd / Consul │ │
│ └──────────┬───────────┘ │
│ │ 控制 │
│ ┌──────────▼───────────┐ │
│ │ 数据平面 │ │
│ │ PostgreSQL 流复制 │ │
│ └──────────────────────┘ │
│ │
│ ┌──────────────────────┐ │
│ │ 访问层 │ │
│ │ VIP / HAProxy / DNS │ │
│ └──────────────────────┘ │
└────────────────────────────┘
分层说明
| 层次 | 组件 | 作用 |
|---|---|---|
| 数据层 | 流复制 | 数据同步 |
| 控制层 | Patroni / repmgr | 选主、切换、防脑裂 |
| 仲裁层 | etcd / Consul | 投票、锁 |
| 访问层 | VIP / HAProxy | 应用找新主 |
六、环境举例
只有流复制
html
10.0.0.18 主
10.0.0.28 备(streaming)
主库宕机:
- 18 挂了
- 28 还是备库
- 应用连 18 超时
- 业务中断
有高可用(Patroni + etcd)
html
10.0.0.18 PG + Patroni
10.0.0.28 PG + Patroni
10.0.0.30 etcd
VIP 10.0.0.10
主库宕机:
- Patroni 检测 18 失联
- etcd leader key 过期
- 28 获得 leader key
- 28 自动
pg_promote() - VIP 漂到 28
- 应用无感知(或短暂重连)
- 18 恢复后自动 rewind 成备库
七、常见误解澄清
❌ 误解 1:流复制就是高可用
✅ 流复制是高可用的基础组件之一
❌ 误解 2:同步复制 = 高可用
同步复制只保证:
主库提交时,备库也收到 WAL
它不解决:
- 主库挂了谁来接管
- 应用怎么连新主
- 脑裂问题
❌ 误解 3:备库能读就是高可用
Hot Standby 只解决:
读负载分担
和高可用无关。
❌ 误解 4:两节点流复制就能高可用
2 个数据库节点:
- 网络分区时
- 各认为对方挂了
- 都升主 → 脑裂
✅ 必须有第 3 票(etcd / witness)
八、能力对照表
| 能力 | 流复制 | 高可用 |
|---|---|---|
| 数据同步 | ✅ | ✅(依赖流复制) |
| 自动故障检测 | ❌ | ✅ |
| 自动选主 | ❌ | ✅ |
| 自动 promote | ❌ | ✅ |
| 防脑裂 | ❌ | ✅ |
| 客户端自动路由 | ❌ | ✅ |
| 老主自动 rewind | ❌ | ✅ |
| 秒级切换 | ❌ | ✅ |
| 零数据丢失 | 可选(同步) | 可选(同步) |
九、一句话总结
流复制是"让备库和主库长得一样"的技术;高可用是"主库死了,备库能自动顶上去,还不出乱子"的系统能力。
十、工程上的正确表述
你应该这样说:
- ✅ "我们用 PostgreSQL 流复制 做数据同步"
- ✅ "我们用 Patroni + 流复制 实现 PostgreSQL 高可用"
- ❌ "我们用流复制做高可用"