十四、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-pusharchive-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-pathrepo1-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_modewal_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
posted @ 2026-09-09 11:53  BinBin-HF  阅读(4)  评论(0)    收藏  举报