导读:本期聚焦于崔健创作的《PostgreSQL 高可用集群如何搭建?流复制与故障切换配置详解》,敬请观看详情。数据库单点故障一旦发生,业务往往直接停摆,PostgreSQL 通过流复制机制可以把主库的数据变更实时同步到备库,配合自动故障切换工具就能构建一套高可用集群。本文从流复制的底层原理讲起,一步步演示主库参数配置、pg_basebackup 基础备份、备库的搭建流程,并介绍同步复制与异步复制的差异、复制槽防止 WAL 日志丢失的用法,最后讲解如何用 Patroni 加 etcd 实现自动选主和故障转移,帮助你搭建一套可落地的 PostgreSQL 高可用方案。

PostgreSQL 原生提供的流复制(Streaming Replication)是构建高可用集群的核心能力。主库产生 WAL 日志后,备库通过网络实时接收并回放这些日志,从而保持与主库的数据一致。当主库发生故障时,备库可以被提升(promote)为新的主库继续对外服务。本文将从原理、搭建步骤、参数调优和自动故障切换四个方面,完整讲解 PostgreSQL 高可用集群的搭建过程。

PostgreSQL 高可用集群如何搭建?流复制与故障切换配置详解

一、流复制的工作原理

PostgreSQL 的流复制基于 WAL(Write-Ahead Log,预写式日志)机制。主库在事务提交前会先把变更写入 WAL 日志,wal sender 进程负责把产生的 WAL 日志段实时推送给备库,备库的 wal receiver 进程接收后写入本地 WAL 文件,再由 startup 进程不断回放日志,达到与主库一致的状态。

与早期的基于文件日志传送方式相比,流复制的优势在于延迟极低。传统的日志传送需要等一个 WAL 段(默认 16MB)写满才归档传输,而流复制是记录级别的推送,主库一旦生成了 WAL 记录,备库几乎可以立即收到,通常延迟在毫秒级别。这也是流复制成为生产环境标配的原因。

流复制分为异步和同步两种模式。异步模式下主库提交事务后不等待备库确认,性能好但主库崩溃时可能丢失最后几毫秒的数据;同步模式下主库会等待至少一个备库确认收到 WAL 后才返回提交成功,数据零丢失但写入延迟会增加。生产环境需要根据业务对数据一致性和性能的要求来选择,例如金融类系统通常配置同步复制,而日志类、统计类业务用异步复制即可。

二、主库与备库的搭建步骤

假设我们有两台服务器:主库 192.168.1.10,备库 192.168.1.11,操作系统为 Linux,已安装 PostgreSQL 14。搭建的第一步是修改主库的 postgresql.conf 核心参数,打开这些参数后重启主库使其生效。

# 主库 postgresql.conf 关键参数
listen_addresses = '*'
wal_level = replica            # 开启 WAL 归档级别,流复制最低要求 replica
max_wal_senders = 10           # 最大 WAL 发送进程数
wal_keep_size = 1024           # 保留 1GB WAL,防止备库取不到日志(PG13 之前为 wal_keep_segments)
hot_standby = on               # 允许备库只读查询(主库上配置,备库继承)
synchronous_commit = on
# 同步复制需要指定同步备库名称
# synchronous_standby_names = 'FIRST 1 (standby1)'

接着配置主库的 pg_hba.conf,允许备库通过复制账号连接。复制账号建议单独创建,只授予复制权限。

# 创建复制用户
createuser -U postgres --replication --login repluser
psql -U postgres -c "ALTER USER repluser PASSWORD 'replpass123';"

# pg_hba.conf 添加一行
host    replication     repluser     192.168.1.11/32     md5

备库端使用 pg_basebackup 从主库拉取基础备份,这一步会完整复制主库数据目录并自动生成 standby.signal 文件(PG12 及以后版本用该文件表示备库身份,替代了早期的 recovery.conf)。

# 在备库服务器执行
pg_basebackup -h 192.168.1.10 -U repluser -D /var/lib/postgresql/14/main \
  -Fp -Xs -P -R \
  -C -S slot_standby1

# 参数说明:
# -Fp  备份为普通文件格式
# -Xs  以流方式同步 WAL
# -R   自动写入 standby.signal 和 primary_conninfo
# -C -S 创建名为 slot_standby1 的物理复制槽

启动备库后,在主库上执行查询即可验证复制状态。如果 state 列显示 streaming,说明流复制已经正常工作。

-- 主库上查看复制状态
SELECT client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn
FROM pg_stat_replication;

-- 备库上查看回放进度,false 表示处于恢复模式即备库
SELECT pg_is_in_recovery();

-- 计算复制延迟(字节)
SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)
FROM pg_stat_replication;

三、复制槽与延迟监控

异步复制有一个隐患:如果备库长时间宕机,主库可能因为 wal_keep_size 保留的 WAL 不够用而不得不删除旧日志,导致备库再也无法追上主库,只能重建。物理复制槽(Replication Slot)就是为了解决这个问题,它会保证主库在备库确认接收之前不删除对应的 WAL 日志。

但复制槽也有副作用:如果备库彻底损坏且不再回来,主库会无限堆积 WAL 直至磁盘写满。因此在启用复制槽的同时,建议设置 max_slot_wal_keep_size 参数(PG13 及以上)限制单个复制槽最多保留的 WAL 量,超过上限后主库会删除 WAL 并让该复制槽失效,以此保护主库自身安全。此外,日常运维中要持续监控复制延迟,常用的做法是定时执行 pg_wal_lsn_diff 计算字节差,或者在备库创建心跳表来检测时间层面的延迟。

四、基于 Patroni 的自动故障切换

原生的流复制只解决了数据同步问题,主库故障后仍需人工执行 promote 操作,故障恢复时间得不到保障。生产环境通常引入 Patroni 加 etcd 的组合来实现自动故障切换。Patroni 是一个集群管理组件,它把集群状态(谁是主库、备库列表、复制参数等)存储在 etcd 分布式存储中,通过分布式锁选举主库。

当主库发生故障时,etcd 中的 leader 键过期,其余节点的 Patroni 会发起选举,获得多数票的节点自动执行 promote 成为新主库,其他节点则自动重新指向新主库继续复制,整个过程通常在十几秒内完成,无需人工介入。Patroni 还内置了 watchdog 机制防止脑裂,并且可以在故障切换后自动执行回调脚本重建旧的失败节点。

一个最小化的 Patroni 配置示例如下,每个节点的配置只需修改 name 和连接地址。

scope: pgcluster
namespace: /service/
name: node1                     # 每个节点唯一
restapi:
  listen: 192.168.1.10:8008
  connect_address: 192.168.1.10:8008
etcd:
  hosts: 192.168.1.20:2379      # etcd 集群地址
postgresql:
  listen: 192.168.1.10:5432
  connect_address: 192.168.1.10:5432
  data_dir: /var/lib/postgresql/14/main
  pgpass: /tmp/pgpass
  authentication:
    superuser:
      username: postgres
      password: pgpass123
    replication:
      username: repluser
      password: replpass123
  parameters:
    wal_level: replica
    max_wal_senders: 10
    hot_standby: on
tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false

配置完成后在各节点启动 Patroni 服务,使用 patronictl list 命令即可查看集群拓扑。应用层建议配合 HAProxy 暴露读写端口,HAProxy 通过 Patroni 的 REST 接口(8008 端口的 master 或 replica 路径)做健康检查,读写请求始终路由到当前主库,只读请求可以分发到备库,实现读写分离与故障切换对应用透明。

五、常见问题与注意事项

搭建过程中有几个高频问题值得注意。第一,防火墙和 pg_hba.conf 必须同时放行,缺一个都会导致 wal sender 连接失败,表现为备库日志中反复出现连接超时。第二,备库的数据目录必须为空且属主为 postgres 用户,否则 pg_basebackup 会直接报错退出。第三,升级 PostgreSQL 大版本后,pg_wal 目录改名为 pg_wal(早期为 pg_xlog),部分监控脚本需要同步调整。

另外要理解 RPO 和 RTO 的关系:异步复制 RPO 不是零,故障时可能丢失最近几百毫秒的提交事务;同步复制虽然 RPO 为零,但备库故障会阻塞主库提交,因此生产上常用 FIRST 1 (node1, node2) 配两个候选同步备库,即所谓的一主一同步一异步的准同步架构,在数据安全与可用性之间取得平衡。完成集群搭建后,务必进行故障演练,手动 kill 主库进程验证自动切换和应用的 reconnect 机制,确保高可用方案真正经得起考验。

PostgreSQL高可用流复制Patroni修改时间:2026-09-02 17:07:21

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260902/49058.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。