十四、PostgreSQL 物理备份 - pgBackRest
1. 简介
pgBackRest 是一个专为 PostgreSQL 设计的开源备份与恢复系统,其目标是在高效扩展到大型数据库和高工作负载的同时,提供可靠的备份能力。
1.1 主要特性
|
并行备份与恢复
|
通过
process-max 参数控制并行进程数,将压缩和数据传输分配到多个进程中。官方建议备份时不超过可用 CPU 的 25%,恢复操作可以使用更多 CPU(因为此时 PostgreSQL 通常已停止)。 |
|
本地/远程操作
|
支持通过 SSH 或 pgBackRest 原生 TLS 协议进行远程备份/恢复/归档操作。也支持从 Standby 备份以减少主库负载。
|
|
多种备份类型
|
Full(全量)、Differential(差异)、Incremental(增量)三种类型。第一次备份必须是全量备份;如果请求增量备份但没有已有备份,pgBackRest 会自动执行全量备份。
|
|
备份加密
|
使用
aes-256-cbc 算法对整个备份仓库进行客户端加密,即使底层存储提供加密也可额外使用。 |
|
多种存储后端
|
本地磁盘、远程主机、S3、Azure Blob Storage、GCS 兼容对象存储。
|
|
多仓库支持
|
可以同时配置多个备份仓库,实现冗余存储。
|
|
WAL 归档
|
提供
archive-push 和 archive-get 命令管理 WAL 段文件;支持异步归档(archive-async)。 |
|
压缩
|
支持 LZ4、Zstandard 等多种压缩算法。
|
|
文件打包与块增量
|
File bundling 和 block-incremental 备份可以提高效率,尤其在对象存储上。
|
2. 概念
2.1 备份类型
- Full(全量备份): 复制整个 PostgreSQL 集群。这是 pgBackRest 的第一次备份必须执行的类型。
-
Differential(差异备份): 仅复制自上一次全量备份以来发生变化的文件。
-
Incremental(增量备份): 仅复制自上一次备份(无论是 Full、Diff 还是 Incr)以来发生变化的文件。
2.2 Stanza(配置段)
Stanza 定义了 pgBackRest 管理的 PostgreSQL 集群。例如
[demo]。在命令行中通过 --stanza=demo 引用。2.3 仓库(Repository)
仓库是存储备份和归档 WAL 的位置。通过
repo1-path、repo1-retention-full 等选项配置。仓库可以位于本地存储、远程主机或 S3/Azure/GCS 兼容的对象存储上。2.4 架构模式
单主机模式: PostgreSQL 和备份仓库在同一台机器上。
专用仓库主机模式(推荐生产环境): PostgreSQL 主机和仓库主机分离,确保数据库主机丢失不会同时摧毁备份。
在专用仓库主机架构中:
- PostgreSQL 主机配置 中使用
repo1-host指向远程仓库服务器 - 仓库主机配置 中使用
pg1-host指向远程 PostgreSQL 服务器 - 备份/过期操作通常从仓库主机发起
重要: 仓库主机上安装的 pgBackRest 版本必须与 PostgreSQL 主机上的版本完全一致。
3. 安装
pgBackRest 推荐通过发行版包安装,而非从源码编译。包管理器会自动处理可执行文件、依赖项、目录和相关系统集成。
3.1 通过包安装(推荐)
Debian / Ubuntu
使用 PostgreSQL 官方 APT 仓库(
apt.postgresql.org):# 配置 PGDG APT 仓库
sudo apt install -y postgresql-common ca-certificates
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
# 安装 pgBackRest
sudo apt update
sudo apt install pgbackrest
# 验证
pgbackrest version
RHEL / Rocky Linux / AlmaLinux
使用 PostgreSQL 官方 Yum/DNF 仓库(
yum.postgresql.org):# 安装 pgBackRest
sudo dnf install pgbackrest
# 验证
pgbackrest version
3.2 从源码编译安装
当没有合适的包可用时,可以从源码编译。官方建议在单独的编译主机上构建,而非在生产 PostgreSQL 服务器上安装编译依赖。pgBackRest 编译后是一个单一可执行文件,可以直接复制到目标主机。
注意: 旧版 pgBackRest 使用 Perl 实现;现代 pgBackRest 是编译型的,使用 Meson/Ninja 构建系统。
安装编译依赖(Debian/Ubuntu)
sudo apt-get install \
python3-distutils meson gcc libpq-dev libssl-dev \
libxml2-dev pkg-config liblz4-dev libzstd-dev \
libbz2-dev libz-dev
下载并编译
从源代码构建时,最好使用构建主机,而不是在生产环境中构建。生成所需的许多工具通常不应安装在生产环境中。pgBackRest 由一个可执行文件组成,因此一旦构建就很容易复制到新主机。
# 下载源码
sudo mkdir -p /build
curl -sL https://github.com/pgbackrest/pgbackrest/releases/download/release%2F2.59.1/pgbackrest-2.59.1.tar.gz |
tar zx -C /build
# 使用 Meson 构建
meson setup /build/pgbackrest /build/pgbackrest-2.59.1
ninja -C /build/pgbackrest
安装可执行文件
sudo cp /build/pgbackrest/src/pgbackrest /usr/bin/pgbackrest
sudo chmod 755 /usr/bin/pgbackrest
# 验证
pgbackrest version
安装运行时依赖和创建目录
# 运行时依赖
sudo apt-get install postgresql-client libxml2 libssh2-1 - 编译安装的PostgreSQL,不需要单独安装postgresql-client
# 创建日志目录
sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown postgres:postgres /var/log/pgbackrest
# 创建配置目录和文件
sudo mkdir -p /etc/pgbackrest
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
sudo chown -R postgres.postgres /etc/pgbackrest/
# 创建本地仓库目录
sudo mkdir -p /pgbackrest
sudo chmod 750 /pgbackrest
sudo chown postgres:postgres /pgbackrest
4. 快速入门配置
4.1 创建配置文件
默认配置文件路径为
/etc/pgbackrest/pgbackrest.conf,默认 include 目录为 /etc/pgbackrest/conf.d。也可以通过 --config、--config-path 和 --config-include-path 覆盖。最小化本地仓库配置示例:
[main]
pg1-path=/data/pgdata/data/
[global]
repo1-path=/pgbackrest
repo1-retention-full=2
start-fast=y
process-max=4
log-level-console=info
log-level-file=detail
[global:archive-push]
compress-level=3
4.2 配置 PostgreSQL WAL 归档
在
postgresql.conf 中设置:wal_level = replica
archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'
修改
archive_mode 和 wal_level 需要重启 PostgreSQL:sudo systemctl restart postgresql
验证配置:
sudo -u postgres psql -c "show wal_level;"
sudo -u postgres psql -c "show archive_mode;"
sudo -u postgres psql -c "show archive_command;"
4.3 创建和验证 Stanza
# 初始化仓库元数据
sudo -u postgres pgbackrest \
--stanza=main \
--log-level-console=info \
stanza-create
# 验证配置
sudo -u postgres pgbackrest \
--stanza=main \
check
# 强制生成可归档的 WAL 段
sudo -u postgres psql -c "select pg_switch_wal();"
# 再次验证
sudo -u postgres pgbackrest --stanza=main check
stanza-create 应在配置 stanza 之后执行,且官方建议在创建后立即运行 check 进行验证。5. 备份操作
5.1 全量备份(Full)
sudo -u postgres pgbackrest \
--stanza=main \
--type=full \
backup
全量备份是后续差异和增量备份的基础。
5.2 差异备份(Differential)
sudo -u postgres pgbackrest \
--stanza=main \
--type=diff \
backup
差异备份包含自上一次全量备份以来的所有变更。
5.3 增量备份(Incremental)
sudo -u postgres pgbackrest \
--stanza=main \
--type=incr \
backup
增量备份基于最近的适用先前备份。可以基于 Full 或 Diff 类型。
5.4 查看备份信息
sudo -u postgres pgbackrest --stanza=main info
5.5 推荐的生产备份计划
|
星期日
|
FULL
|
每周一次全量备份
|
|
星期三
|
DIFF
|
每周中进行一次差异备份
|
|
其他工作日
|
INCR
|
增量备份,基于最近的备份
|
Cron 示例:
# Full - 周日 02:00
0 2 * * 0 postgres pgbackrest --stanza=main --type=full backup
# Differential - 周三 02:00
0 2 * * 3 postgres pgbackrest --stanza=main --type=diff backup
# Incremental - 周一、二、四、五、六 02:00
0 2 * * 1,2,4,5,6 postgres pgbackrest --stanza=main --type=incr backup
6. 恢复操作
6.1 基本恢复
pgBackRest 恢复整个 PostgreSQL 集群。恢复前必须停止 PostgreSQL:
sudo systemctl stop postgresql
sudo -u postgres pgbackrest \
--stanza=main \
restore
sudo systemctl start postgresql
6.2 Delta 恢复
--delta 选项允许在目标目录中有现有内容的情况下恢复。pgBackRest 会比较现有文件与备份,只恢复/删除必要的文件:sudo -u postgres pgbackrest \
--stanza=main \
--delta \
restore
注意: Delta 恢复可以修改/删除目标位置的文件以使其与选定备份匹配。请确保
pg1-path 和 tablespace 映射指向正确的集群。6.3 时间点恢复(PITR)
pgBackRest 可以将数据库恢复到特定时间点。它会自动选择合适的备份并配置 PostgreSQL 通过
archive-get 获取所需的 WAL:sudo -u postgres pgbackrest \
--stanza=main \
--type=time \
--target="2026-09-09 10:30:00+08" \
--target-action=promote \
restore
如需指定特定备份集,可添加
--set=<backup-label>。sudo -u postgres pgbackrest \
--stanza=main \
--type=time \
--set=20260909-130311F \
--target="2026-09-09 10:30:00+08" \
--target-action=promote \
restore
6.4 Tablespace 重映射
恢复时可以将 tablespace 映射到新的物理路径:
# 单独映射
--tablespace-map=ts_data=/newdisk/pg_ts_data
--tablespace-map=ts_index=/newdisk/pg_ts_index
# 将所有 tablespace 映射到统一父目录下
--tablespace-map-all=/data/tablespaces
6.5 完整的 PITR + Delta + Tablespace 恢复示例
sudo -u postgres pgbackrest \
--stanza=prod \
--type=time \
--target="2026-09-09 02:30:00+00" \
--target-action=promote \
--tablespace-map=ts_data=/restore/tablespaces/data \
--tablespace-map=ts_index=/restore/tablespaces/index \
restore
7. 保留策略与过期
7.1 备份保留
通过
repo1-retention-full 控制保留的全量备份数量:repo1-retention-full=4
repo1-retention-full-type=count
当新的全量备份成功完成后,pgBackRest 会根据保留策略自动过期旧备份及其依赖的差异/增量备份。
7.2 WAL 归档保留
通常只需配置备份保留,pgBackRest 会自动推导 WAL 保留策略——保留使已保留备份保持一致性所需的 WAL。可以通过
repo1-retention-archive 更激进地过期 WAL,但这会缩短可用的 PITR 窗口。7.3 Expire 命令
成功的
backup 命令会自动执行过期操作。通常不需要单独运行 expire,但可以手动执行:# 预览(不实际删除)
sudo -u postgres pgbackrest --stanza=main expire --dry-run
# 实际执行过期
sudo -u postgres pgbackrest --stanza=main expire
提示: 在调整更激进的归档保留策略之前,建议先使用
--dry-run 评估影响。8. WAL 归档(archive-push & archive-get)
8.1 archive-push
archive-push 由 PostgreSQL 在需要归档 WAL 时自动调用(通过 archive_command),不需要通过 cron 调度:archive_command = 'pgbackrest --stanza=main archive-push %p'
8.2 archive-get
archive-get 在恢复或 Standby 需要归档 WAL 时由 PostgreSQL 调用。pgBackRest 在恢复时会自动配置等效的 restore_command:restore_command = 'pgbackrest --stanza=main archive-get %f "%p"'
8.3 异步归档(Async)
异步归档允许 pgBackRest 并行处理 WAL 和预取队列,在仓库位于远程/高延迟存储(如 S3)时尤为有用:
[global]
archive-async=y
spool-path=/var/spool/pgbackrest
[global:archive-push]
process-max=4
[global:archive-get]
process-max=2
archive-get-queue-max=1GiB
异步
archive-get 使用 spool 目录作为本地预取队列——当 PostgreSQL 请求 WAL N 时,后台 worker 会异步预取 N+1、N+2、N+3...,当队列降到一半以下时会继续补充。9. 专用仓库主机配置
9.1 SSH 方式
PostgreSQL 主机配置(
/etc/pgbackrest/pgbackrest.conf):[prod]
pg1-path=/var/lib/postgresql/17/main
[global]
repo1-host=backup.example.com
repo1-host-user=pgbackrest
repo1-host-type=ssh
repo1-retention-full=4
repo1-retention-diff=4
仓库主机配置(
/etc/pgbackrest/pgbackrest.conf):[prod]
pg1-host=db.example.com
pg1-host-user=postgres
pg1-path=/var/lib/postgresql/17/main
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=4
repo1-retention-diff=4
创建仓库账户和目录:
useradd -m pgbackrest
mkdir -p /var/lib/pgbackrest
chown pgbackrest:pgbackrest /var/lib/pgbackrest
chmod 750 /var/lib/pgbackrest
建立双向免密 SSH:
# 仓库主机 -> PostgreSQL 主机
sudo -u pgbackrest ssh postgres@pg-primary
# PostgreSQL 主机 -> 仓库主机
sudo -u postgres ssh pgbackrest@repository
安全建议: 官方建议限制 authorized SSH key 的权限,使其只能执行 pgBackRest 而非提供不受限的 shell 访问。
9.2 TLS 方式(推荐新部署)
TLS 方式避免了 SSH 账户依赖,pgBackRest 有专门的 TLS 服务端,默认监听端口 8432。
PostgreSQL 主机配置:
[prod]
pg1-path=/var/lib/postgresql/17/main
[global]
repo1-host=backup.example.com
repo1-host-type=tls
repo1-host-ca-file=/etc/pgbackrest/cert/ca.crt
repo1-host-cert-file=/etc/pgbackrest/cert/db.crt
repo1-host-key-file=/etc/pgbackrest/cert/db.key
repo1-retention-full=4
repo1-retention-diff=4
仓库主机配置:
[prod]
pg1-host=db.example.com
pg1-host-type=tls
pg1-host-ca-file=/etc/pgbackrest/cert/ca.crt
pg1-host-cert-file=/etc/pgbackrest/cert/repository-client.crt
pg1-host-key-file=/etc/pgbackrest/cert/repository-client.key
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=4
repo1-retention-diff=4
tls-server-address=*
tls-server-ca-file=/etc/pgbackrest/cert/ca.crt
tls-server-cert-file=/etc/pgbackrest/cert/repository.crt
tls-server-key-file=/etc/pgbackrest/cert/repository.key
tls-server-auth=db-client=prod
tls-server-auth 控制哪个证书身份可以访问哪个 stanza。TLS 服务器需要在两端运行,因为仓库主机发起的操作也需要联系 PostgreSQL 主机。9.3 验证专用仓库主机
# 在仓库主机上创建 stanza
sudo -u pgbackrest pgbackrest --stanza=prod stanza-create
# 在 PostgreSQL 主机上检查
sudo -u postgres pgbackrest --stanza=prod check
# 在仓库主机上检查
sudo -u pgbackrest pgbackrest --stanza=prod check
10. 加密配置
pgBackRest 支持对整个备份仓库进行客户端加密:
[main]
pg1-path=/var/lib/postgresql/17/main
[global]
repo1-path=/var/lib/pgbackrest
repo1-cipher-type=aes-256-cbc
repo1-cipher-pass=YOUR_SECRET_PASSPHRASE
process-max=4
注意: 加密是由 pgBackRest 执行的客户端加密,即使底层存储(如 S3 SSE)提供自身的加密,也可叠加使用。请务必安全保管 cipher-pass,丢失密码将无法恢复备份!
11. 常用命令速查
pgbackrest --stanza=main stanza-create |
初始化仓库元数据
|
pgbackrest --stanza=main check |
验证 PostgreSQL + WAL 归档配置
|
pgbackrest --stanza=main --type=full backup |
执行全量备份
|
pgbackrest --stanza=main --type=diff backup |
执行差异备份
|
pgbackrest --stanza=main --type=incr backup |
执行增量备份
|
pgbackrest --stanza=main info |
查看备份信息
|
pgbackrest --stanza=main restore |
恢复备份
|
pgbackrest --stanza=main expire --dry-run |
预览过期操作
|
pgbackrest --stanza=main verify |
验证仓库完整性
|
psql -c "select pg_switch_wal();" |
强制 WAL 切换(测试归档)
|
psql -x -c "select * from pg_stat_archiver;" |
查看 PostgreSQL 归档统计
|
12. 生产环境完整配置参考
# /etc/pgbackrest/pgbackrest.conf — 生产环境参考
[prod]
pg1-path=/var/lib/postgresql/17/main
[global]
repo1-path=/backup/pgbackrest
# 保留 4 个全量备份
repo1-retention-full=4
repo1-retention-full-type=count
# 快速启动备份(不等待 checkpoint 自然完成)
start-fast=y
# 并行处理
process-max=4
# 异步 WAL 归档
archive-async=y
spool-path=/var/spool/pgbackrest
# 日志
log-level-console=info
log-level-file=detail
[global:archive-push]
process-max=4
[global:archive-get]
process-max=2
archive-get-queue-max=1GiB
PostgreSQL 配置:
# postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'pgbackrest --stanza=prod archive-push %p'
本文档翻译自 pgBackRest User Guide,基于 pgBackRest 2.59.1 版本。部分内容经过整理和重组以便于中文读者阅读。如需查看完整的配置选项参考,请访问 pgBackRest Configuration Reference。
浙公网安备 33010602011771号