PostgreSQL 流复制与逻辑复制性能优化与故障切换实战经验分享
PostgreSQL 流复制与逻辑复制性能优化与故障切换实战经验分享
在高可用和数据安全愈发受到重视的生产环境中,PostgreSQL 复制技术是保障业务连续性的重要手段。本文结合真实生产场景,分享流复制(Physical Replication)与逻辑复制(Logical Replication)的架构设计、性能优化和故障切换实战经验。
1. 业务场景描述
- 主库承载日均千万级写入请求,读请求峰值达2000 QPS。
- 需要实时备库做故障切换,且对主从延迟(Replication Lag)有严格要求(<100ms)。
- 希望在无需停机的情况下进行版本升级或跨数据中心切换。
- 同时需要对部分表或数据库进行灵活的逻辑订阅,以支持分库分表后数据同步。
2. 技术选型过程
- 流复制:内置、稳定,对全库一致性保证强,适合主从切换或流量剪切。
- 逻辑复制:基于发布/订阅,可选择性同步表结构变更,支持跨版本/跨架构迁移。
- 工具选型:使用官方 replication slot+pg_basebackup 搭建流复制,逻辑复制使用
CREATE PUBLICATION
/CREATE SUBSCRIPTION
。故障切换借助pg_ctl promote
或第三方repmgr
。
最终方案:主备采用流复制+同步提交(synchronous commit),跨 DC 或分库场景使用逻辑复制。
3. 实现方案详解
3.1 流复制部署
- 主库配置(postgresql.conf):
# WAL 级别
wal_level = logical # 支持逻辑复制可选 physical
max_wal_senders = 10 # 并发复制连接数
max_replication_slots = 10 # 复制槽
wal_keep_segments = 128 # 保留WAL段避免过快清理
synchronous_commit = on # 开启同步提交
synchronous_standby_names = 'standby1' # 同步备库名称
- 主库认证(pg_hba.conf):
# 允许复制用户连接
host replication replicator 192.168.1.0/24 md5
- 创建复制用户:
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'StrongP@ssw0rd';
- 初始化备库:
pg_basebackup -h 主库IP -D /data/pgsql/primary2 -U replicator -X stream -P
- 备库配置(recovery.conf 或 postgresql.auto.conf):
standby_mode = 'on'
primary_conninfo = 'host=主库IP port=5432 user=replicator password=StrongP@ssw0rd'
recovery_target_timeline = 'latest'
# 可选:故障切换触发
trigger_file = '/data/pgsql/trigger.promote'
- 启动备库:
pg_ctl -D /data/pgsql/primary2 start
3.2 逻辑复制部署
- 主库开启逻辑复制支持:
wal_level = logical
max_worker_processes = 8
max_replication_slots = 8
max_wal_senders = 8
- 创建发布:
-- 发布所有表
CREATE PUBLICATION pub_all FOR ALL TABLES;
-- 发布单表
CREATE PUBLICATION pub_user FOR TABLE public.user;
- 目标库创建订阅:
CREATE SUBSCRIPTION sub_all CONNECTION 'host=主库IP port=5432 dbname=postgres user=replicator password=StrongP@ssw0rd'PUBLICATION pub_all;
- 验证延迟:
-- 查看逻辑订阅状态
SELECT * FROM pg_stat_subscription;
4. 踩过的坑与解决方案
-
WAL 段过快清理导致备库初始化失败
- 原因:
wal_keep_segments
配置过小 - 方案:适当增大
wal_keep_segments
或使用archive_mode
+archive_command
长期保存WAL。
- 原因:
-
复制槽堆积导致磁盘占满
- 原因:逻辑复制槽未及时消费
- 方案:定期监控
pg_replication_slots
,必要时手动清理或调整max_replication_slots
。
-
主从切换后客户端连接抖动
- 原因:应用侧未配置连接重试和读写分离
- 方案:使用 PgBouncer 或 HAProxy 实现健康检查和自动路由。
-
版本升级时逻辑复制不兼容
- 原因:跨主次版本时 WAL 格式或目录结构变化
- 方案:升级前先测试 publication/subscription 兼容性,必要时使用双写中间件平滑切换。
-
同步提交性能瓶颈
- 原因:synchronous_commit 阻塞主库写入
- 方案:仅对关键库开启同步提交,其他只用异步模式;或者使用半同步模式(
remote_write
)。
5. 总结与最佳实践
- 对业务关键表使用流复制+同步模式,保障零数据丢失。
- 对灵活拆库、跨 DC 场景使用逻辑复制,按需订阅表。
- 生产环境中要覆盖 WAL 归档、复制槽监控、连接池与中间件容灾。
- 灰度或测试环境定期演练故障切换,验证
pg_ctl promote
和连接重试策略。 - 持续关注
pg_stat_replication
、pg_stat_subscription
延迟指标,自动告警。
通过以上实战经验的分享,希望帮助后端开发及 DBA 在高并发场景下,结合业务需求选择合适的 PostgreSQL 复制方案,并在性能优化与故障切换实践中少走弯路。