PostgreSQL 支持哪几种复制(Replication)方式?
PostgreSQL 提供了非常强大且灵活的复制(Replication)功能,以满足高可用性(HA)、灾难恢复(DR)、读写分离以及数据集成等不同场景的需求。
总体来说,PostgreSQL 的复制方式主要分为两大阵营:物理复制(Physical Replication) 和 逻辑复制(Logical Replication)。此外,还有一些基于第三方的解决方案。
以下是 PostgreSQL 支持的主要复制方式详解:
一、 物理复制 (Physical Replication)
物理复制是基于块(Block)级别的复制,即备库(Standby)是主库(Primary)在磁盘层面的完全一致的逐位拷贝(Bit-for-bit copy)。它通过传输和应用 WAL(Write-Ahead Log,预写式日志) 来实现。
物理复制主要有以下几种形式:
1. 流复制 (Streaming Replication) —— 最常用
这是目前 PostgreSQL 最常用、推荐的高可用和读写分离方案。主库在生成 WAL 记录时,不需要等 WAL 文件写满,而是直接通过网络流式传输给备库,备库接收到后立即应用。
- 异步流复制 (Asynchronous): (默认模式)主库提交事务时,不等待备库确认即可返回成功。性能极高,但在主库突然宕机时,可能会丢失极少量的未传输数据。
- 同步流复制 (Synchronous): 主库提交事务时,必须等待一个或多个备库确认已接收并写入 WAL 后,才向客户端返回成功。保证零数据丢失 (RPO=0),但会受网络延迟影响,降低主库的写入性能。
2. 基于文件的日志传送 (File-based WAL Shipping / Warm Standby)
这是较早期的复制方式。主库将写满的 16MB WAL 文件通过 archive_command(如 scp, rsync, 存入 S3 等)归档并传送到备库,备库通过 restore_command 读取并恢复这些文件。
- 特点: 延迟较高(因为必须等 16MB 文件写完才传送),通常不单独使用,而是与流复制结合使用,作为流复制网络中断时的“兜底”机制。
物理复制的优缺点:
- ✅ 优点: 性能高、配置相对简单、支持 DDL(表结构变更)的同步、备库可以作为只读节点分担查询压力(Hot Standby)。
- ❌ 缺点: 备库必须是只读的(不能写操作);只能复制整个数据库集群,不能只复制单表;要求主备库的 PostgreSQL 大版本和操作系统架构完全一致。
二、 逻辑复制 (Logical Replication)
逻辑复制是 PostgreSQL 10 引入的原生功能。它基于数据行的变化(INSERT/UPDATE/DELETE)进行复制,采用 发布/订阅 (Publish/Subscribe) 模型。它通过逻辑解码(Logical Decoding)把底层的 WAL 日志解析成可读的 SQL 操作,然后再发送给订阅端。
- 发布者 (Publisher): 在源数据库上定义,决定把哪些表的数据变化发送出去。
- 订阅者 (Subscriber): 在目标数据库上定义,接收变化并应用到本地。
逻辑复制的优缺点与适用场景:
- ✅ 优点(适用场景):
- 细粒度: 可以只复制特定的表,甚至特定的行/列(通过行过滤和列过滤)。
- 跨版本升级: 支持不同大版本的 PostgreSQL 之间同步(例如从 PG 11 平滑迁移到 PG 16)。
- 跨平台: 可以在不同操作系统(如 Linux 到 Windows)之间复制。
- 目标库可写: 订阅库不仅可以接收数据,还可以进行其他的读写操作,方便做数据汇总(将多个系统的数据同步到一个数据仓库)。
- ❌ 缺点: 性能开销稍大于物理复制;默认不同步 DDL(表结构变更);不同步序列(Sequences);处理大事务时可能会消耗较多内存。
三、 第三方/高级复制方案
虽然 PostgreSQL 原生支持强大的主从复制,但在某些特定场景下(如多主复制),需要借助第三方插件或扩展:
1. 多主复制 (Multi-Master Replication)
原生 PG 不支持多主写入(即多个节点都能同时读写同一张表并相互同步)。实现多主复制通常需要:
- BDR (Bi-Directional Replication): 基于逻辑复制开发的高级企业级多主复制方案(目前主要由 EDB 提供商业支持)。
- Bucardo: 一个开源的、基于触发器(Trigger)的异步多主复制工具。支持多主节点冲突解决。
- SymmetricDS: 支持异构数据库同步的多主复制中间件。
2. 基于触发器的复制 (Trigger-based Replication - 历史方案)
在 PG 10 原生逻辑复制出现之前,人们常用基于触发器的工具来实现单表或部分数据的同步。
- Slony-I: 最古老、最成熟的基于触发器的复制工具,但配置复杂,目前已较少新项目使用。
- Londiste (SkyTools): 由 Skype 开发,基于队列的复制工具。
3. 分布式/分片集群
- Citus: PostgreSQL 的官方扩展,将单机 PG 变成分布式数据库,支持数据分片、分布式查询和自带的高可用复制机制。
总结与选型建议
| 需求场景 | 推荐的复制方式 |
|---|---|
| 常规高可用 (HA) 与灾备 (DR) | 原生异步或同步流复制(结合 Patroni/Keepalived 等管理工具) |
| 读写分离 (分担查询压力) | 原生异步流复制 (Hot Standby) |
| 只同步某几张表 | 原生逻辑复制 |
| 不停机跨大版本升级 PostgreSQL | 原生逻辑复制 |
| 多个业务库数据汇总到一台数据仓库 | 原生逻辑复制 |
| 多个节点同时读写同一张表 | 第三方工具(BDR、Bucardo) |