pgBackRest 集中备份实战:从单节点到 Patroni 集群
在生产环境中,PostgreSQL 的高可用通常由 Patroni 管理,但数据安全最终要靠可靠的备份系统。本文将记录如何为 Patroni 集群部署 pgBackRest 集中备份,实现全量 + 差异 + WAL 归档的自动化策略,并验证恢复流程。
1. 环境概览
集群架构
- Patroni 管理的 PostgreSQL 17 集群(3 节点)
- 备份服务器独立部署,作为集中备份仓库
1 2 3 4 5 6 7 8
| Patroni 集群节点: - Leader: 10.0.181.92 - Replica: 10.0.181.90 - Replica: 10.0.181.94
备份服务器: - 主机: backup.example.com (10.0.200.100) - 仓库路径: /backup/pgbackrest
|
核心原则
- 所有数据库节点安装 pgBackRest,作为客户端
- 备份服务器安装 pgBackRest,作为存储服务端
- 通过 SSH 协议实现节点到备份服务器的数据传输
- 备份策略:每周全量、每日差异、每小时 WAL 归档
2. 安装 pgBackRest
2.1 编译安装(适用于所有节点)
从 2.50 版本起,pgBackRest 使用 meson 构建。以 2.55.0 为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| yum install -y gcc make meson ninja-build \ libxml2-devel openssl-devel libzstd-devel \ liblz4-devel bzip2-devel libssh2-devel
wget https://github.com/pgbackrest/pgbackrest/archive/refs/tags/release/2.55.0.tar.gz tar xzf 2.55.0.tar.gz cd pgbackrest-release-2.55.0
meson setup build ninja -C build ninja -C build install
pgbackrest version
|
2.2 使用包管理器快速安装(可选)
1 2
| yum install -y pgbackrest
|
3. 目录与权限规划
3.1 数据库节点
创建配置目录,并确保 postgres 用户拥有权限:
1 2
| mkdir -p /etc/pgbackrest chown -R postgres:postgres /etc/pgbackrest
|
3.2 备份服务器
创建仓库目录和日志目录:
1 2
| mkdir -p /backup/pgbackrest /var/log/pgbackrest chown -R postgres:postgres /backup/pgbackrest /var/log/pgbackrest
|
4. SSH 免密配置
备份服务器需要接受来自数据库节点的 SSH 连接,用于传输备份和 WAL。
在每个数据库节点上(以 postgres 用户执行):
1 2
| ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" ssh-copy-id postgres@backup.example.com
|
测试连接:
1
| ssh postgres@backup.example.com "echo OK"
|
5. pgBackRest 配置文件
5.1 数据库节点配置 (/etc/pgbackrest/pgbackrest.conf)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| [global]
repo1-host=backup.example.com repo1-host-user=postgres repo1-path=/backup/pgbackrest repo1-retention-full=2 repo1-retention-diff=4 repo1-bundle=y
log-level-console=info log-path=/var/log/pgbackrest
process-max=4
compress-type=lz4
[patroni-cluster] pg1-path=/var/lib/postgresql/data pg1-port=5432 pg1-socket-path=/var/run/postgresql
|
注意:如果 PostgreSQL 运行在容器中,pg1-path 应指向容器内的数据目录,确保 pgBackRest 能访问到。建议将数据目录挂载到宿主机相同路径,或通过符号链接解决。
5.2 备份服务器配置 (/etc/pgbackrest/pgbackrest.conf)
备份服务器只需要知道仓库位置,无需 stanza 定义:
1 2 3
| [global] repo1-path=/backup/pgbackrest log-path=/var/log/pgbackrest
|
6. PostgreSQL 归档配置
在每个数据库节点的 postgresql.conf 中开启归档:
1 2 3 4 5
| wal_level = replica archive_mode = on archive_command = 'pgbackrest --stanza=patroni-cluster archive-push %p' archive_timeout = 60 max_wal_senders = 10
|
重启 PostgreSQL 或执行 pg_ctl reload 使配置生效。在 Patroni 环境下,可以通过调整动态参数并触发 reload:
1 2
| ALTER SYSTEM SET archive_command = 'pgbackrest --stanza=patroni-cluster archive-push %p'; SELECT pg_reload_conf();
|
7. 创建 Stanza 并验证
在 Leader 节点上执行(确保当前节点为 Primary):
1 2 3 4 5
| pgbackrest --stanza=patroni-cluster stanza-create
pgbackrest --stanza=patroni-cluster check
|
check 命令会验证:
- PostgreSQL 能正常连接
- archive_command 可执行
- 备份服务器可写
如果一切正常,输出类似:
1
| 2026-03-13 10:00:00.000 P00 INFO: check command end: completed successfully
|
8. 执行首次备份
全量备份
1
| pgbackrest --stanza=patroni-cluster --type=full backup
|
增量/差异备份
1 2 3 4 5
| pgbackrest --stanza=patroni-cluster backup
pgbackrest --stanza=patroni-cluster --type=diff backup
|
查看备份信息
1
| pgbackrest --stanza=patroni-cluster info
|
输出示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| stanza: patroni-cluster status: ok cipher: none
db (current) wal archive min/max (17): 000000010000000000000001/000000010000000000000005
full backup: 20260313-100000F timestamp start/stop: 2026-03-13 10:00:00+08 / 2026-03-13 10:05:12+08 wal start/stop: 000000010000000000000002 / 000000010000000000000003 database size: 1.2TB, database backup size: 1.2TB repo1: backup set size: 256.8GB, backup size: 256.8GB
diff backup: 20260313-120000D ...
|
9. 生产备份策略自动化
使用 crontab 在 Leader 节点上调度备份任务(需确保 cron 环境能找到 pgbackrest 和正确配置):
1 2 3 4 5 6 7 8
| crontab -e -u postgres
0 2 * * 0 pgbackrest --stanza=patroni-cluster --type=full backup
0 2 * * 1-6 pgbackrest --stanza=patroni-cluster --type=diff backup
|
WAL 归档由 PostgreSQL 自动触发,无需额外 cron。
10. 恢复演练
10.1 查看可用的备份时间线
1
| pgbackrest --stanza=patroni-cluster info
|
10.2 在测试环境恢复最新备份
模拟故障:清空数据目录,执行恢复。
1 2 3 4 5 6 7 8 9
| systemctl stop patroni rm -rf /var/lib/postgresql/data/*
pgbackrest --stanza=patroni-cluster restore
systemctl start patroni
|
10.3 时间点恢复 (PITR)
恢复到指定时间点(例如 2026-03-13 14:30:00):
1 2 3 4
| pgbackrest --stanza=patroni-cluster \ --type=time \ --target="2026-03-13 14:30:00+08" \ restore
|
恢复完成后,数据库处于只读模式,需手动创建恢复标记或通过 pg_wal_replay_resume() 继续。
10.4 恢复后验证
1 2
| SELECT count(*) FROM important_table;
|
11. 集成 Patroni 集群恢复
在 Patroni 集群中,恢复通常只针对单个节点(如 Leader 故障后重建)。流程:
- 停止故障节点的 Patroni
- 清空 PGDATA
- 执行 pgBackRest 恢复(使用
--delta 选项可增量恢复)
- 启动 Patroni,让其通过 pg_rewind 或全量重建追上集群
1 2 3 4
| systemctl stop patroni rm -rf /var/lib/postgresql/data/* pgbackrest --stanza=patroni-cluster restore --delta systemctl start patroni
|
Patroni 会自动识别数据目录并启动,然后作为新副本加入集群。
12. 企业级优化与监控
优化配置
在配置文件 [global] 中增加:
1 2 3 4 5
| compress-type=lz4 process-max=8 repo1-bundle=y repo1-cipher-type=aes-256-cbc start-fast=y
|
监控集成
- 通过
pgbackrest info 获取备份状态
- 使用 Prometheus exporter (
pgbackrest_exporter) 采集指标
- 关键指标:
last_backup_timestamp、wal_archive_lag
设置定时检查脚本,若备份滞后超过阈值则告警。
13. 常见故障处理
| 现象 |
排查步骤 |
| WAL 未归档 |
检查archive_command 能否手动执行,查看 pgBackRest 日志 /var/log/pgbackrest/*.log |
| 备份失败 |
执行pgbackrest --stanza=patroni-cluster check,检查 SSH 连通性和仓库权限 |
| 恢复失败 |
确保数据目录为空,或使用--delta 覆盖现有文件;检查 PostgreSQL 版本是否匹配 |
| 备份速度慢 |
增加process-max,使用 LZ4 压缩,启用 repo1-bundle,检查网络带宽 |
14. 总结
通过 pgBackRest 为 Patroni 集群构建集中备份,我们实现了:
- 独立备份仓库,与数据库节点分离
- 自动化全量/差异备份 + 持续 WAL 归档
- 任意时间点恢复(PITR)
- 与 Patroni 无缝集成,故障重建自动化
- 企业级特性:压缩、加密、并行、校验
按照本文步骤操作,你可以为生产环境的 PostgreSQL Patroni 集群搭建一个可靠、高效的备份系统,满足 RPO < 1min、RTO < 10min 的高标准要求。
最后提醒:定期进行恢复演练(每季度至少一次),验证备份的有效性,并测试恢复流程的顺畅性。备份不仅是拷贝数据,更是为了能在灾难时快速恢复业务。
本文环境基于 PostgreSQL 17 + Patroni 4.0.6 + pgBackRest 2.55.0,操作系统为 RHEL 9。如有差异,请根据实际情况调整。