本指南基于"最简单、最实用"的原则编写,面向数据库管理员和运维人员,涵盖从环境准备、策略配置到灾难恢复的全流程。
1. 概述
本指南介绍如何在单机 Linux 环境下部署 pgBackRest,实现 PostgreSQL 数据库的自动化备份(全量 + 差异/增量),并在发生误删除等故障时,通过时间点恢复(PITR)技术将数据还原至故障前的任意一秒。
核心优势:
- 自动化:通过 Cron 定时任务自动执行。
- 高效性:支持并行压缩、差异/增量备份,节省存储空间。
- 精准恢复:支持恢复到任意时间点(精确到秒),无需回滚整个备份链。
2. 环境准备
2.1 前置条件
| 项目 | 要求 |
|---|---|
| 操作系统 | CentOS 7+ / Ubuntu 18.04+ |
| 数据库 | PostgreSQL(已安装并运行) |
| 工具 | pgBackRest(已通过 yum 或 apt 安装) |
2.2 用户与权限模型
这是最容易混淆的地方,请务必理解。
pgBackRest 涉及两个系统用户,它们各司其职:
| 用户 | 职责 |
|---|---|
postgres |
PostgreSQL 进程的运行用户,拥有数据目录(pg1-path)的读写权限。负责触发归档命令(archive_command)。备份恢复时也需使用此用户执行 restore。 |
pgbackrest |
备份工具的专用用户,拥有备份仓库目录(repo1-path)的读写权限。负责执行日常备份任务(backup)。 |
两个用户之间通过配置文件共享协作,无需互相拥有对方目录的权限。
2.3 创建备份仓库目录
bash
# 1. 创建仓库目录
sudo mkdir -p /var/lib/pgbackrest
# 2. 若安装包未自动创建 pgbackrest 用户,手动创建
sudo useradd -r -m -s /bin/false pgbackrest
# 3. 仓库目录授权给 pgbackrest 用户
sudo chown -R pgbackrest:pgbackrest /var/lib/pgbackrest
sudo chmod 750 /var/lib/pgbackrest
# 4. 创建日志目录
sudo mkdir -p /var/log/pgbackrest
sudo chown -R pgbackrest:pgbackrest /var/log/pgbackrest
2.4 确认 PostgreSQL 数据目录路径
不同发行版的默认路径不同,请先确认,后续配置会用到:
sql
-- 在 psql 中执行
SHOW data_directory;
| 发行版 | 典型默认路径 |
|---|---|
| Ubuntu / Debian | /var/lib/postgresql/17/main |
| CentOS / RHEL / Rocky | /var/lib/pgsql/17/data |
3. 配置步骤
3.1 配置 pgBackRest
编辑配置文件 /etc/pgbackrest/pgbackrest.conf,请将 pg1-path 替换为上一步确认的实际路径:
ini
[global]
# 备份仓库路径
repo1-path=/var/lib/pgbackrest
# 保留策略:保留最近 2 个全量备份(旧备份会被自动清理)
repo1-retention-full=2
# 并行进程数(建议设为 CPU 核数的一半)
process-max=2
# 压缩算法(zstd 压缩率高且速度快,推荐)
compress-type=zstd
# 开启详细日志,便于排查问题
log-level-file=detail
[mydb]
# 替换为你的实际 PostgreSQL 数据目录
pg1-path=/var/lib/postgresql/17/main
3.2 配置 PostgreSQL 开启 WAL 归档
PITR 的核心依赖是连续的 WAL 日志归档,此步骤必不可少。
编辑 postgresql.conf(位于 pg1-path 目录下):
ini
# 开启归档模式
archive_mode = on
# 将 WAL 日志交由 pgBackRest 处理
# 注意:archive_command 由 postgres 用户触发执行
archive_command = 'pgbackrest --stanza=mydb archive-push %p'
# WAL 级别需为 replica 或更高
wal_level = replica
重启数据库使配置生效:
bash
sudo systemctl restart postgresql
3.3 初始化 Stanza 并验证
第一步:初始化 (以 pgbackrest 用户执行)
bash
sudo -u pgbackrest pgbackrest --stanza=mydb stanza-create
第二步:验证归档链路是否打通( 此步骤不可跳过)
bash
sudo -u pgbackrest pgbackrest --stanza=mydb check
执行后观察输出,所有项均为 ok 才代表配置成功。如果 archive-push 报错,通常是 archive_command 中的权限问题,检查 postgres 用户是否能直接调用 pgbackrest 命令(可在 shell 中手动测试)。
4. 自动化备份策略
采用 "每周全量 + 每日差异" 策略,平衡存储空间与恢复速度。
4.1 立即执行第一次全量备份
配置完成后必须先手动执行一次全量备份! 在第一个全量备份完成之前,差异备份和 PITR 均无法工作。在等到下一个周日之前,请先手动执行:
bash
sudo -u pgbackrest pgbackrest --stanza=mydb --type=full backup
4.2 配置 Cron 定时任务
bash
sudo crontab -u pgbackrest -e
添加以下内容:
bash
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# 每周日 02:00 执行全量备份
0 2 * * 0 /usr/bin/pgbackrest --stanza=mydb --type=full backup --log-level-console=warn
# 周一至周六 02:00 执行差异备份
0 2 * * 1-6 /usr/bin/pgbackrest --stanza=mydb --type=diff backup --log-level-console=warn
说明:WAL 日志归档是实时的,由数据库进程自动触发,无需配置到 Cron。
5. 灾难恢复实战(PITR)
场景假设
- 当前时间:周四 16:01
- 故障时间:14:55 发生误删除操作
- 恢复目标 :将数据库恢复到
14:54:59(误操作前一秒)
pgBackRest 会自动选择最近的备份(如当天 02:00 的差异备份),并结合 WAL 日志回放至指定时间点。
方案一:直接恢复到指定时间点(时间点已明确时)
步骤 1:停止数据库
bash
sudo systemctl stop postgresql
步骤 2:执行还原
restore命令需要写入 PostgreSQL 数据目录,因此必须以postgres用户执行。
bash
sudo -u postgres pgbackrest \
--stanza=mydb \
--type=time \
--target="2026-03-19 14:54:59" \
--delta \
restore
参数说明:
| 参数 | 说明 |
|---|---|
--type=time |
按时间点恢复 |
--target |
目标时间,替换为实际故障前的时间 |
--delta |
增量还原,仅替换有差异的文件,速度更快 |
步骤 3:启动数据库
bash
sudo systemctl start postgresql
步骤 4:验证数据
bash
psql -c "SELECT * FROM 被误删的表 LIMIT 5;"
方案二:暂停模式(不确定精确时间点时,推荐)
数据库恢复后进入只读状态,确认数据无误后再手动激活,避免时间点不准确导致的二次破坏。
步骤 1:停止数据库
bash
sudo systemctl stop postgresql
步骤 2:执行还原(暂停模式)
bash
sudo -u postgres pgbackrest \
--stanza=mydb \
--type=time \
--target="2026-03-19 14:55:00" \
--recovery-option=recovery_target_action=pause \
--delta \
restore
步骤 3:启动数据库(此时为只读)
bash
sudo systemctl start postgresql
步骤 4:检查数据是否正确
bash
psql -c "SELECT * FROM 被误删的表 LIMIT 5;"
步骤 5a:数据正确 → 激活数据库
sql
SELECT pg_wal_replay_resume();
步骤 5b:数据不正确 → 重新调整时间点
bash
# 停库
sudo systemctl stop postgresql
# 调整 --target 时间后重新执行步骤 2
6. 常用维护命令
| 操作 | 命令 | 说明 |
|---|---|---|
| 查看备份列表 | pgbackrest --stanza=mydb info |
查看备份的大小、时间、状态 |
| 手动全量备份 | pgbackrest --stanza=mydb --type=full backup |
立即执行全量备份 |
| 手动差异备份 | pgbackrest --stanza=mydb --type=diff backup |
立即执行差异备份 |
| 验证配置 | pgbackrest --stanza=mydb check |
验证配置和归档链路是否正常 |
| 过期清理 | (自动执行) | 根据 repo1-retention-full 自动清理旧备份 |
7. 注意事项
-
时间同步 :确保服务器启用了 NTP(
timedatectl status可检查),时钟不准会导致 PITR 失败。 -
WAL 连续性 :PITR 依赖连续的 WAL 归档,切勿手动删除归档目录中的任何文件,pgBackRest 会根据保留策略自动管理。
-
定期恢复演练:备份的价值在于能成功恢复。建议每季度在测试环境执行一次完整的恢复演练,验证备份有效性。
-
restore用户 :还原操作需使用postgres用户执行,而非pgbackrest用户,因为需要写入数据目录。 -
先做全量备份:配置完成后必须立即手动执行一次全量备份,否则自动备份任务无法正常工作。
备份的价值不在于"备",而在于"恢"。通过 pgBackRest 的 PITR 功能,您可以从容应对误删除、数据损坏等突发状况,将数据丢失风险降至最低。