📦 pgBackRest 教学 PostgreSQL
从官方指南简化而来 · 面向 PostgreSQL 运维人员
1. 简介
pgBackRest 是最流行的 PostgreSQL 备份恢复工具之一,特点是:
- 高性能 — 并行备份/还原、压缩、流式 WAL 归档
- 企业级 — 全量/差异/增量备份、时间点恢复 (PITR)
- 多种存储 — 本地、NFS、S3、Azure、GCS、SFTP
- 加密 — 客户端 AES-256 加密
- 可靠 — 自动校验、一致性检查
💡 推荐阅读顺序:本指南建议按顺序从头到尾阅读,因为每个部分依赖前一部分。首次配置建议走一遍"快速上手"。
2. 核心概念
2.1 备份类型
| 类型 | 特点 | 容量 | 还原依赖 |
| Full (全量) | 复制整个集群 | 最大 | 独立 |
| Differential (差异) | 自上次全量以来变更的文件 | 中等 | 依赖最近的 Full |
| Incremental (增量) | 自上次任何备份以来变更的文件 | 最小 | 依赖最近的 Full + 所有上游增量 |
首次备份必须是 Full。之后 pgBackRest 默认尝试增量,但如果没有 Full 做基础则自动降级为 Full。
2.2 Restore(还原)
把备份复制到一个系统并启动为可用的数据库集群。还原需要备份文件 + 对应时间范围内的 WAL 段。
2.3 WAL (Write Ahead Log)
PostgreSQL 的预写日志。所有事务先写入 WAL(16MB/段),再刷到数据文件。WAL 归档是 Point-in-Time Recovery 的基础。
WAL 段命名示例:0000000100000A1E000000FE(前 8 位 = 时间线,后 16 位 = LSN)。
2.4 加密
pgBackRest 使用 AES-256-CBC 对存储库进行加密。密钥用 openssl rand -base64 48 生成。
⚠️ 一旦创建并初始化 Stanza 后,加密设置不可更改。
3. 安装
推荐从 RPM 包安装(yum.postgresql.org)。也可以从源码编译:
# 安装依赖
sudo yum install meson gcc postgresql13-devel openssl-devel \
libxml2-devel lz4-devel libzstd-devel bzip2-devel libyaml-devel
# 下载并编译
wget -q -O - \
https://github.com/pgbackrest/pgbackrest/archive/release/2.58.0.tar.gz | \
tar zx -C /build
meson setup /build/pgbackrest /build/pgbackrest-release-2.58.0
ninja -C /build/pgbackrest
# 安装二进制
sudo cp /build/pgbackrest/pgbackrest /usr/bin/
sudo chmod 755 /usr/bin/pgbackrest
# 创建目录和配置
sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown postgres:postgres /var/log/pgbackrest
sudo mkdir -p /etc/pgbackrest/conf.d
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf
⚠️ 安全注意:配置文件和日志目录的所有权必须为 postgres 用户,权限分别为 640 和 770。
4. 快速上手
以下配置使用一个名为 pg-primary 的主机,PostgreSQL 13,Stanza 名为 demo。
4.1 配置 Stanza
Stanza 是 pgBackRest 对 PostgreSQL 集群的配置定义,包含数据目录、备份路径、归档选项等。编辑 /etc/pgbackrest/pgbackrest.conf:
[demo]
pg1-path=/var/lib/pgsql/13/data
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
💡 Stanza 命名建议:不要用主机名,而用数据库描述性名称(如"demo"),因为主从共用同一 Stanza 名。
4.2 创建 Repository
Repository 是存储备份和 WAL 归档的目录。
sudo mkdir -p /var/lib/pgbackrest
sudo chmod 750 /var/lib/pgbackrest
sudo chown postgres:postgres /var/lib/pgbackrest
4.3 配置归档 & 保留策略
编辑 PostgreSQL 配置 /var/lib/pgsql/13/data/postgresql.conf:
archive_mode = on
archive_command = 'pgbackrest --stanza=demo archive-push %p'
listen_addresses = '*'
log_filename = 'postgresql.log'
添加保留策略(在 pgbackrest.conf 的 [global] 段):
repo1-retention-full=2 # 保留 2 个全量备份
repo1-retention-diff=1 # 保留 1 个差异备份
重启 PostgreSQL:
sudo systemctl restart postgresql-13.service
4.4 创建 Stanza & 验证
# 创建 Stanza
sudo -u postgres pgbackrest --stanza=demo --log-level-console=info stanza-create
# 验证配置
sudo -u postgres pgbackrest --stanza=demo --log-level-console=info check
check 命令会验证归档和备份配置是否正确,并触发一次 WAL 归档测试。
4.5 执行备份
# 首次备份(自动 Full)
sudo -u postgres pgbackrest --stanza=demo --log-level-console=info backup
# 差异备份
sudo -u postgres pgbackrest --stanza=demo --type=diff --log-level-console=info backup
# 增量备份
sudo -u postgres pgbackrest --stanza=demo --type=incr --log-level-console=info backup
# 指定全量
sudo -u postgres pgbackrest --stanza=demo --type=full --log-level-console=info backup
💡 注意:默认 pgBackRest 等待下一个 check point 后才开始备份。加上 --start-fast 可强制立即 check point。
4.6 定时备份 & 查看信息
# crontab 示例
# 每周日 6:30 全量备份
30 6 * * 0 pgbackrest --stanza=demo --type=full backup
# 周一至周六 6:30 差异备份
30 6 * * 1-6 pgbackrest --stanza=demo --type=diff backup
# 查看备份信息
sudo -u postgres pgbackrest info
# JSON 格式(机器可读)
sudo -u postgres pgbackrest --output=json info
pgbackrest info 输出示例:
stanza: demo
status: ok
cipher: aes-256-cbc
db (current)
wal archive min/max (13): 00000001.../00000001...
full backup: 20260119-092100F
timestamp start/stop: 2026-01-19 09:21:00+00 / 09:21:02+00
database size: 23.2MB, backup size: 2.9MB
diff backup: 20260119-092100F_20260119-092102D
database size: 23.2MB, backup size: 9.1KB
标签含义:F = Full, D = Differential, I = Incremental
4.7 还原备份
# 模拟损坏:删除 pg_control 文件
sudo systemctl stop postgresql-13.service
sudo -u postgres rm /var/lib/pgsql/13/data/global/pg_control
# 清空数据目录并还原
sudo -u postgres find /var/lib/pgsql/13/data -mindepth 1 -delete
sudo -u postgres pgbackrest --stanza=demo restore
# 启动
sudo systemctl start postgresql-13.service
5. 备份详解
5.1 文件打包 (File Bundling)
将多个小文件打包成一个大文件,减少 Repository 中的文件数量,尤其适合 S3 等对象存储:
# 在 pgbackrest.conf 中启用
repo1-bundle=y
启用后,全量备份文件数从 1000+ 降到个位数。零长度文件不再存储(除清单外)。
5.2 块增量 (Block Incremental)
只保存文件中发生变化的部分,而非整个文件。需要同时启用文件打包:
repo1-block=y # 启用块增量
repo1-bundle=y # 文件打包(必须同时启用)
5.3 备份注解 (Annotations)
为备份添加键值对标注:
# 备份时添加标注
sudo -u postgres pgbackrest --stanza=demo \
--annotation=source="demo backup" --annotation=key=value --type=full backup
# 查看标注(指定备份集)
sudo -u postgres pgbackrest --stanza=demo --set=20260119-092115F info
# 修改/删除标注
sudo -u postgres pgbackrest --stanza=demo --set=20260119-092115F \
--annotation=key= --annotation=new_key=new_value annotate
6. 保留策略
| 选项 | 说明 | 示例 |
| repo1-retention-full | 保留的全量备份数(或天数) | repo1-retention-full=2 |
| repo1-retention-full-type | 计数或时间 | count (默认) / time |
| repo1-retention-diff | 保留的差异备份数 | repo1-retention-diff=1 |
| repo1-retention-archive-type | WAL 归档保留策略 | full / diff |
| repo1-retention-archive | 保留的归档数 | repo1-retention-archive=1 |
💡 保留策略机制:
- expire 命令在每次成功备份后自动执行
- 差异备份过期不会早于其依赖的全量备份
- 增量备份过期不会早于其依赖的差异/全量备份
- WAL 归档默认保留到其相关的全量备份过期为止
- 可通过 retention-archive 更激进地清理 WAL(注意:PITR 依赖连续 WAL 流)
7. 还原详解
7.1 File Ownership
以非 root 用户还原时,文件所有权为执行用户。以 root 还原时,pgBackRest 会尝试恢复备份时记录的所有权(需要相同用户名存在)。
7.2 Delta 选项(推荐)
自动比对已有文件与备份,只覆盖/删除有差异的文件,无需手动清空数据目录:
sudo -u postgres pgbackrest --stanza=demo --delta --log-level-console=detail restore
7.3 选择性还原数据库
只还原特定数据库,节省空间:
# 只还原 test2 数据库
sudo -u postgres pgbackrest --stanza=demo --delta \
--db-include=test2 --type=immediate --target-action=promote restore
⚠️ 未选中的数据库会被还原为稀疏零文件——可应用 WAL 但无法查询。恢复后需执行 DROP DATABASE 清理。
8. 时间点恢复 (PITR)
PITR 是 pgBackRest 最重要的功能之一——恢复被误删的表/数据:
# 1. 记录"事故前"的时间
sudo -u postgres psql -Atc "select current_timestamp"
# → 2026-01-19 09:21:46.275227+00
# 2. 模拟误删表
sudo -u postgres psql -c "drop table important_table;"
# 3. 还原到事故前
sudo systemctl stop postgresql-13.service
sudo -u postgres pgbackrest --stanza=demo --delta \
--type=time "--target=2026-01-19 09:21:46.275227+00" \
--target-action=promote restore
sudo systemctl start postgresql-13.service
# 4. 验证数据已恢复
sudo -u postgres psql -c "select * from important_table"
| 选项 | 说明 |
| --type=time | 按时间恢复(需指定 --target) |
| --type=lsn | 按 LSN 恢复 |
| --type=immediate | 停止点恢复(不指定目标) |
| --target | 目标时间/LSN/XID |
| --target-action=promote | 达到目标后自动提升为主库 |
| --target-timeline=current | 使用当前时间线 |
| --set | 指定要还原的备份集 |
💡 PITR 关键要点:
1. 时间点要包含时区偏移(如 +00)
2. 如指定的备份不包含目标时间,还原会失败——建议不指定 --set,让 pgBackRest 自动选择
3. 还原后 pgBackRest 会自动生成 postgresql.auto.conf(含恢复配置),可直接启动
9. 监控
在 PostgreSQL 中创建函数来查询备份信息:
-- 创建监控 schema 和函数
CREATE SCHEMA monitor;
CREATE FUNCTION monitor.pgbackrest_info()
RETURNS jsonb AS $$
DECLARE
result jsonb;
BEGIN
COPY (SELECT pgbackrest.info()) TO '/tmp/pgbackrest-info.json';
SELECT pg_read_file('/tmp/pgbackrest-info.json')::jsonb INTO result;
RETURN result;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 查询最新备份
WITH stanza AS (
SELECT data->'name' AS name,
data->'backup'->(jsonb_array_length(data->'backup') - 1) AS last_backup,
data->'archive'->(jsonb_array_length(data->'archive') - 1) AS last_archive
FROM jsonb_array_elements(monitor.pgbackrest_info()) AS data
)
SELECT name, last_backup->>'timestamp_stop' AS last_backup_time
FROM stanza;
建议监控的指标:
- 最近成功备份时间(超过 24 小时无成功备份应告警)
- WAL 归档延迟
- 备份大小趋势(磁盘空间预测)
10. 配置速查
pgBackRest 配置文件格式:Windows INI 风格。位于 /etc/pgbackrest/pgbackrest.conf + conf.d/ 目录。环境变量也可配置。
# 典型完整配置
[demo]
pg1-path=/var/lib/pgsql/13/data
pg1-port=5432
[global]
# Repository
repo1-path=/var/lib/pgbackrest
repo1-cipher-type=aes-256-cbc
repo1-cipher-pass=
# 保留策略
repo1-retention-full=2
repo1-retention-full-type=count
repo1-retention-diff=1
# 性能
repo1-bundle=y # 文件打包
repo1-block=y # 块增量
process-max=4 # 并行进程数
compress-type=zst # 压缩算法 (zst/lz4/gz/bz2/none)
compress-level=6 # 压缩级别
# 归档
archive-timeout=60 # WAL 归档超时(秒)
archive-async=y # 异步归档
# 日志
log-level-console=info # 控制台日志级别
log-level-file=detail # 文件日志级别
| 配置加载顺序 | 说明 |
| pgbackrest.conf | 主配置文件 |
| conf.d/*.conf | 按字母顺序加载,可覆盖主配置 |
| 环境变量 | 最高优先级,如 PGBACKREST_REPO1_PATH |
常见命令速查
| 命令 | 作用 |
| pgbackrest stanza-create | 初始化 Stanza |
| pgbackrest check | 验证配置 + 归档 |
| pgbackrest backup | 执行备份 |
| pgbackrest restore | 还原备份 |
| pgbackrest info | 查看备份信息 |
| pgbackrest expire | 手动过期旧备份 |
| pgbackrest archive-push | 推送 WAL 到归档 |
| pgbackrest archive-get | 从归档获取 WAL |
| pgbackrest stanza-delete | 删除 Stanza |
| pgbackrest annotate | 管理备份注解 |
📝 思考题:
1. 你有一个 500GB 的 PostgreSQL 库,每天产生 10GB WAL。你希望保留 7 天的 PITR 能力,同时每周做一个全量备份。你会怎么配置保留策略?
2. 某天你发现有人误删了一张核心表,30 分钟后才发现。你该用什么命令恢复?
3. 你的备份目录在 S3 上,发现 Repository 里有 10 万个文件。应该开启什么选项优化性能?