1. PostgreSQL主从复制架构解析
PostgreSQL的流复制(Streaming Replication)是构建高可用数据库集群的核心技术。我在金融行业数据库运维中,曾用这套方案将系统可用性从99.9%提升到99.99%。与MySQL基于binlog的复制不同,PostgreSQL采用WAL(预写式日志)传输机制,这带来了几个独特优势:
- 数据一致性更强:WAL记录的是物理页变化,从库应用日志后与主库字节级一致
- 同步模式更灵活:支持同步/异步/级联等多种复制拓扑
- 故障恢复更快:备库持续应用WAL,切换时RPO(恢复点目标)接近0
关键理解:WAL就像飞机黑匣子,完整记录所有数据变更操作。主库不断"直播"WAL记录,从库实时"追剧"应用这些变更。
2. 环境准备与参数配置
2.1 硬件规划建议
在生产环境部署时,我推荐以下配置:
| 组件 | 主库规格 | 从库规格 | 备注 | |-------------|---------------------|---------------------|-------------------------------| | CPU | 16核+ | ≥主库核心数 | 避免从库重放成为瓶颈 | | 内存 | 32GB+ | ≥主库内存 | 共享缓冲区大小需一致 | | 磁盘 | SSD/NVMe | 同主库 | 建议RAID10 | | 网络带宽 | 1Gbps+专用网络 | 同主库 | 延迟<1ms |2.2 关键参数配置
主库postgresql.conf中必须修改:
wal_level = replica # WAL日志级别 max_wal_senders = 5 # 最大WAL发送进程数 synchronous_commit = on # 同步提交保证数据安全从库recovery.conf中配置:
standby_mode = on primary_conninfo = 'host=主库IP port=5432 user=repl_user password=密码' trigger_file = '/tmp/promote_to_primary' # 用于手动切换主从踩坑记录:曾经因max_wal_senders设置过小导致从库断开连接,建议生产环境至少设置5个发送进程。
3. 详细搭建步骤
3.1 主库准备
- 创建复制专用账号:
CREATE ROLE repl_user WITH REPLICATION LOGIN PASSWORD 'securePassword';- 配置pg_hba.conf允许从库连接:
host replication repl_user 从库IP/32 md5- 重启PostgreSQL服务使配置生效:
sudo systemctl restart postgresql-123.2 从库初始化
推荐使用pg_basebackup进行基础备份:
pg_basebackup -h 主库IP -U repl_user -D /var/lib/pgsql/12/data -P -v -R -X stream参数说明:
-P显示进度-v详细输出-R自动创建recovery.conf-X stream流式传输WAL日志
4. 复制监控与维护
4.1 监控指标
通过以下SQL监控复制状态:
SELECT client_addr, state, sync_state, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes, EXTRACT(EPOCH FROM (now() - replay_lag)) AS lag_seconds FROM pg_stat_replication;关键字段解读:
lag_bytes:WAL应用延迟字节数lag_seconds:数据延迟秒数sync_state:同步模式(async/quorum/sync)
4.2 日常维护
延迟处理方案:
- 网络问题:检查
ping 主库IP和traceroute - 从库性能瓶颈:检查CPU/IO使用率
- 大事务:拆分超过100MB的单个事务
定期检查清单:
- 每月验证从库数据一致性:
pg_checksums - 季度性切换演练:测试故障转移流程
- 监控WAL归档空间:至少保留3天量
5. 高可用方案进阶
5.1 同步复制优化
对于金融级场景,建议配置:
synchronous_standby_names = 'FIRST 2 (slave1, slave2)'这表示:
- 至少2个从库确认接收WAL后主库才提交
- 按slave1、slave2优先级选择同步从库
5.2 自动故障转移
结合Patroni实现自动切换:
postgresql: parameters: wal_level: replica hot_standby: "on" use_pg_rewind: true recovery_conf: restore_command: cp /var/lib/pgsql/wal_archive/%f %p关键功能:
- 主库故障时自动选举新主
- 旧主恢复后自动加入集群
- 支持pg_rewind修复分歧
6. 性能调优实战
6.1 WAL调优参数
wal_compression = on # 压缩WAL减少网络传输 wal_buffers = 16MB # 大型事务时增加 max_wal_size = 4GB # 根据写入量调整 min_wal_size = 1GB6.2 从库查询优化
启用hot_standby并设置:
hot_standby = on max_standby_streaming_delay = 30s hot_standby_feedback = on这允许:
- 从库执行只读查询
- 控制查询冲突时的最大延迟
- 向主库反馈长查询避免清理冲突
7. 常见故障处理
7.1 复制中断恢复
当出现"requested WAL segment has already been removed"错误时:
- 从库执行:
pg_rewind --target-pgdata=/var/lib/pgsql/12/data \ --source-server="host=主库IP user=postgres"- 重新创建recovery.conf启动复制
7.2 主从不一致修复
使用pg_compare工具检查:
pg_compare -h 主库IP -U postgres -d mydb \ -H 从库IP -U postgres -D mydb \ --table=critical_table差异修复方案:
- 小量差异:手动SQL修正
- 大量差异:重建从库
8. 生产环境经验
8.1 版本升级策略
采用滚动升级:
- 升级从库PostgreSQL版本
- 故障转移到新版本从库
- 原主库升级后作为新从库加入
8.2 备份整合方案
我设计的备份架构:
主库 → WAL归档 → S3 ↓ 从库 → pg_basebackup → NAS关键点:
- 主库只归档WAL减轻负载
- 从库执行全量备份
- 保留7天循环备份+1个月冷备
在最近一次数据中心级故障中,这套方案帮助我们在28分钟内完成了TB级数据库的完整恢复。