PostgreSQL + Pgpool + Barman WAL Streaming 到 S3 SOP
目录
1. 背景与目标
- 现状:生产环境使用 pgpool 管理 PostgreSQL 高可用(主从切换由 pgpool 决策)。
- 目标:在不调整任何 PostgreSQL 或 pgpool 配置的前提下,新增 Barman,使用 WAL Streaming 持续备份到本地,并将备份仓库近实时同步到 S3;提供可操作的 SOP,支持点时间恢复(PITR)。
- 原理要点:
- WAL Streaming 提供低延迟、持续复制能力,适合高可用场景。
- 将 Barman 仓库同步到 S3 提供异地冗余与时间点恢复能力。
- 不启用 archive_command;通过流式拉取实现冗余与补齐。
2. 架构概览
- 组件:
- barman:拉取 WAL、管理备份与保留策略、执行 cron。
- s3sync:周期性使用 awscli 将 Barman 仓库同步到 S3。
- primary-watcher:连接 pgpool,查询当前 primary 节点,动态更新 barman 的连接目标,自动感知主从切换。
- scheduler(可选):每日触发一次基线备份(base backup)。
- 数据流:PostgreSQL 主库 → Barman(pg_receivewal 流式)→ 本地仓库 → S3 同步。
- 约束:不修改 postgresql.conf、pgpool 配置或启用 archive_command。
架构图(Mermaid)
flowchart LR
%% 对外应用经由 pgpool 访问数据库;Barman 直连主库做 WAL 拉取与备份,并将仓库同步到 S3;primary-watcher 通过 pgpool 感知主从切换
subgraph Clients[业务访问层]
APP[应用/服务]
end
APP -->|读写路由| PGPOOL[(pgpool)]
subgraph DB[数据库高可用集群]
PG_PRIMARY[(PostgreSQL 主库)] --- PG_STANDBY[(PostgreSQL 备库)]
end
PGPOOL -->|主库连接| PG_PRIMARY
PGPOOL -->|只读连接| PG_STANDBY
subgraph BackupPlane[备份平面]
PRIMARY_WATCHER[primary-watcher\n通过 pgpool 感知主库]
BARMAN[Barman\nWAL Streaming + Base Backup]
LOCAL[(本地Barman仓库)]
S3SYNC[s3sync\naws s3 sync]
S3[(S3 Bucket/prefix)]
SCHEDULER[scheduler\n每日基线备份]
end
%% 感知与更新
PRIMARY_WATCHER -->|show pool_nodes| PGPOOL
PRIMARY_WATCHER -->|更新 conninfo.host| BARMAN
%% 备份与同步
BARMAN -->|直连| PG_PRIMARY
BARMAN --> LOCAL
SCHEDULER -->|触发 base backup| BARMAN
S3SYNC --> LOCAL
S3SYNC -->|同步到云端| S3
%% 只用于感知,不经 pgpool 进行物理复制
classDef note fill:#fff9c4,stroke:#fbc02d,color:#8a6d3bflowchart LR
%% 对外应用经由 pgpool 访问数据库;Barman 直连主库做 WAL 拉取与备份,并将仓库同步到 S3;primary-watcher 通过 pgpool 感知主从切换
subgraph Clients[业务访问层]
APP[应用/服务]
end
APP -->|读写路由| PGPOOL[(pgpool)]
subgraph DB[数据库高可用集群]
PG_PRIMARY[(PostgreSQL 主库)] --- PG_STANDBY[(PostgreSQL 备库)]
end
PGPOOL -->|主库连接| PG_PRIMARY
PGPOOL -->|只读连接| PG_STANDBY
subgraph BackupPlane[备份平面]
PRIMARY_WATCHER[primary-watcher\n通过 pgpool 感知主库]
BARMAN[Barman\nWAL Streaming + Base Backup]
LOCAL[(本地Barman仓库)]
S3SYNC[s3sync\naws s3 sync]
S3[(S3 Bucket/prefix)]
SCHEDULER[scheduler\n每日基线备份]
end
%% 感知与更新
PRIMARY_WATCHER -->|show pool_nodes| PGPOOL
PRIMARY_WATCHER -->|更新 conninfo.host| BARMAN
%% 备份与同步
BARMAN -->|直连| PG_PRIMARY
BARMAN --> LOCAL
SCHEDULER -->|触发 base backup| BARMAN
S3SYNC --> LOCAL
S3SYNC -->|同步到云端| S3
%% 只用于感知,不经 pgpool 进行物理复制
classDef note fill:#fff9c4,stroke:#fbc02d,color:#8a6d3bflowchart LR
%% 对外应用经由 pgpool 访问数据库;Barman 直连主库做 WAL 拉取与备份,并将仓库同步到 S3;primary-watcher 通过 pgpool 感知主从切换
subgraph Clients[业务访问层]
APP[应用/服务]
end
APP -->|读写路由| PGPOOL[(pgpool)]
subgraph DB[数据库高可用集群]
PG_PRIMARY[(PostgreSQL 主库)] --- PG_STANDBY[(PostgreSQL 备库)]
end
PGPOOL -->|主库连接| PG_PRIMARY
PGPOOL -->|只读连接| PG_STANDBY
subgraph BackupPlane[备份平面]
PRIMARY_WATCHER[primary-watcher\n通过 pgpool 感知主库]
BARMAN[Barman\nWAL Streaming + Base Backup]
LOCAL[(本地Barman仓库)]
S3SYNC[s3sync\naws s3 sync]
S3[(S3 Bucket/prefix)]
SCHEDULER[scheduler\n每日基线备份]
end
%% 感知与更新
PRIMARY_WATCHER -->|show pool_nodes| PGPOOL
PRIMARY_WATCHER -->|更新 conninfo.host| BARMAN
%% 备份与同步
BARMAN -->|直连| PG_PRIMARY
BARMAN --> LOCAL
SCHEDULER -->|触发 base backup| BARMAN
S3SYNC --> LOCAL
S3SYNC -->|同步到云端| S3
%% 只用于感知,不经 pgpool 进行物理复制
classDef note fill:#fff9c4,stroke:#fbc02d,color:#8a6d3bflowchart LR
%% 对外应用经由 pgpool 访问数据库;Barman 直连主库做 WAL 拉取与备份,并将仓库同步到 S3;primary-watcher 通过 pgpool 感知主从切换
subgraph Clients[业务访问层]
APP[应用/服务]
end
APP -->|读写路由| PGPOOL[(pgpool)]
subgraph DB[数据库高可用集群]
PG_PRIMARY[(PostgreSQL 主库)] --- PG_STANDBY[(PostgreSQL 备库)]
end
PGPOOL -->|主库连接| PG_PRIMARY
PGPOOL -->|只读连接| PG_STANDBY
subgraph BackupPlane[备份平面]
PRIMARY_WATCHER[primary-watcher\n通过 pgpool 感知主库]
BARMAN[Barman\nWAL Streaming + Base Backup]
LOCAL[(本地Barman仓库)]
S3SYNC[s3sync\naws s3 sync]
S3[(S3 Bucket/prefix)]
SCHEDULER[scheduler\n每日基线备份]
end
%% 感知与更新
PRIMARY_WATCHER -->|show pool_nodes| PGPOOL
PRIMARY_WATCHER -->|更新 conninfo.host| BARMAN
%% 备份与同步
BARMAN -->|直连| PG_PRIMARY
BARMAN --> LOCAL
SCHEDULER -->|触发 base backup| BARMAN
S3SYNC --> LOCAL
S3SYNC -->|同步到云端| S3
%% 只用于感知,不经 pgpool 进行物理复制
classDef note fill:#fff9c4,stroke:#fbc02d,color:#8a6d3b3. 前提条件
- 网络:barman 容器到各 PostgreSQL 节点 5432 可达;pgpool 5432/PCP 端口可达(用于“感知”主从,不用于复制)。
- 账号:
复制用户(主库执行):
1CREATE ROLE barman REPLICATION LOGIN PASSWORD '强密码';pgpool 管理查询用户(可执行 show pool_nodes 的只读账号)。
- S3:已创建 bucket 与前缀(如 s3://pg-backup/cluster-a/),配置最小权限的 IAM。
- 运行方式:所有第三方组件使用 Docker 容器运行。
4. 环境变量与目录布局
建议在部署目录设置以下环境变量(通过 .env 或 Compose 环境段传入):
- PRIMARY_WATCH_HOST=pgpool 地址
- PRIMARY_WATCH_PORT=5432
- PRIMARY_WATCH_USER=只读管理用户
- PRIMARY_WATCH_PASSWORD=该用户密码
- BARMAN_PASSWORD=barman 复制用户密码
- AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_DEFAULT_REGION
- S3_BUCKET=pg-backup
- S3_PREFIX=cluster-a
目录结构(宿主机):
- ./barman/etc/barman.conf
- ./barman/etc/conf.d/my_pg_server.conf
- ./barman/var/ (Barman 仓库数据)
- ./barman/log/ (日志)
5. Barman 配置示例
/barman/etc/barman.conf:
1 2 3 4 5 6 7[barman] barman_user = barman barman_home = /var/lib/barman log_file = /var/log/barman/barman.log compression = gzip reuse_backup = link retention_policy = REDUNDANCY 2/barman/etc/conf.d/my_pg_server.conf:
1 2 3 4 5 6 7 8 9 10 11[my_pg_server] description = "Primary PostgreSQL" conninfo = host=INIT_PRIMARY port=5432 user=barman dbname=postgres password=BARMAN_PASSWORD backup_method = postgres streaming_archiver = on slot_name = barman create_slot = auto archiver = off streaming_backup_name = streaming retention_policy_mode = auto retention_policy = REDUNDANCY 2
说明:conninfo 的 host 将由 primary-watcher 自动更新为当前主库地址。
6. Docker Compose 部署
| |
部署:
| |
7. 验证步骤
列出服务器并检查:
1 2docker exec barman barman list-server docker exec barman barman check my_pg_server触发一次基线备份:
1docker exec barman barman backup my_pg_server查看本地 WAL 与备份生成情况:
1ls ./barman/var/my_pg_server -R | head校验 S3 同步:
1aws s3 ls s3://${S3_BUCKET}/${S3_PREFIX}/ --recursive | head
8. 故障切换感知与演练
- 原理:primary-watcher 通过 pgpool 的 show pool_nodes 获取 role=primary 的节点 IP/主机名;变化时更新 barman 的 conninfo,下一轮 cron 自动连接新主库继续拉 WAL。
- 演练:
- 触发一次主从切换(按现网流程)。
- 10 秒内 primary-watcher 应更新 conninfo;barman cron 恢复拉流。
- 执行 barman check 确认健康;观察 S3 继续出现新 WAL 文件。
9. 点时间恢复(PITR)
目标:恢复到指定时间点。
步骤:
1 2 3 4 5 6aws s3 sync s3://${S3_BUCKET}/${S3_PREFIX}/ /restore/barman docker run --rm \ -v /restore/barman:/var/lib/barman \ -v /pgdata:/pgdata \ ghcr.io/pgcentralfoundation/barman:3 \ barman recover my_pg_server latest /pgdata --target-time "2026-01-04 10:00:00"启动 PostgreSQL,等待 WAL 回放完成后对外服务。
建议:每季度在隔离环境演练完整恢复;抽查任意日期的还原一致性。
10. 监控与告警
- barman 健康:定时执行 barman check,采集返回码与关键日志。
- 复制槽与延迟:监控 pg_replication_slots、pg_stat_wal_receiver。
- S3 同步:比对本地与 S3 文件数量与更新时间;失败重试与告警。
- 容量与成本:监控 S3 用量、请求次数;按需调整保留策略与备份频率。
11. 保留策略与运行维护
- 保留:retention_policy = REDUNDANCY 2(保留最近两份备份及其 WAL)。
- 运行:barman 每分钟 cron;scheduler 每日基线备份;s3sync 每 30 秒同步。
- 维护:定期清理过期备份、验证备份可用性,评估同步频率与成本。
12. 权限与安全
- IAM 最小权限,仅允许对指定 bucket/prefix 的读写与列举。
- 凭证通过环境变量或 Docker Secrets 提供;不要写入镜像或代码仓库。
- primary-watcher 账号仅需 show pool_nodes 的只读权限。
13. 故障排除
- barman check 失败:查看 ./barman/log/barman.log;确认 conninfo 主机地址与复制用户权限。
- WAL 积压:若复制槽长时间无消费者会导致主库 WAL 磁盘增长;需监控并及时恢复。
- pgpool 列解析:不同版本 show pool_nodes 列位可能差异,必要时打印行样例确认 awk 列号。
- S3 同步异常:检查 awscli 版本、凭证、网络连通性;开启重试与告警。
14. 风险与建议
- 不通过 pgpool 做物理复制,仅用其感知主库角色,降低复制链路复杂度。
- 监控复制槽与磁盘空间,避免 WAL 积压导致主库磁盘吃满。
- 定期演练恢复,确保 RPO/RTO 达标;结合成本优化 S3 周期与保留窗口。
15. 附录:IAM 策略示例
16. 附录:参考
- 云原生运维:https://www.kbsonlong.com/
- Kubernetes 文档:https://kubernetes.io/zh-cn/docs/home/
- Istio 官方文档:https://istio.io/latest/zh/docs/
- Linux 内核文档:https://docs.kernel.org/translations/zh_CN/index.html
- WAL 归档与流式原理:Understanding WAL Archiving and WAL Streaming in PostgreSQL(结合 WAL Streaming 与文件归档的优势,采用流式 + S3 冗余以满足不改主库配置的约束)