pgBackRest 本地备份与灾难恢复实战指南

12 阅读7分钟

本指南基于"最简单、最实用"的原则编写,面向数据库管理员和运维人员,涵盖从环境准备、策略配置到灾难恢复的全流程。


1. 概述

本指南介绍如何在单机 Linux 环境下部署 pgBackRest,实现 PostgreSQL 数据库的自动化备份(全量 + 差异/增量),并在发生误删除等故障时,通过时间点恢复(PITR)技术将数据还原至故障前的任意一秒。

核心优势:

  • 自动化:通过 Cron 定时任务自动执行。
  • 高效性:支持并行压缩、差异/增量备份,节省存储空间。
  • 精准恢复:支持恢复到任意时间点(精确到秒),无需回滚整个备份链。

2. 环境准备

2.1 前置条件

项目要求
操作系统CentOS 7+ / Ubuntu 18.04+
数据库PostgreSQL(已安装并运行)
工具pgBackRest(已通过 yumapt 安装)

2.2 用户与权限模型

这是最容易混淆的地方,请务必理解。

pgBackRest 涉及两个系统用户,它们各司其职:

用户职责
postgresPostgreSQL 进程的运行用户,拥有数据目录(pg1-path)的读写权限。负责触发归档命令(archive_command)。备份恢复时也需使用此用户执行 restore
pgbackrest备份工具的专用用户,拥有备份仓库目录(repo1-path)的读写权限。负责执行日常备份任务(backup)。

两个用户之间通过配置文件共享协作,无需互相拥有对方目录的权限。

2.3 创建备份仓库目录

# 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 数据目录路径

不同发行版的默认路径不同,请先确认,后续配置会用到:

-- 在 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 替换为上一步确认的实际路径

[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 目录下):

# 开启归档模式
archive_mode = on

# 将 WAL 日志交由 pgBackRest 处理
# 注意:archive_command 由 postgres 用户触发执行
archive_command = 'pgbackrest --stanza=mydb archive-push %p'

# WAL 级别需为 replica 或更高
wal_level = replica

重启数据库使配置生效:

sudo systemctl restart postgresql

3.3 初始化 Stanza 并验证

第一步:初始化(以 pgbackrest 用户执行)

sudo -u pgbackrest pgbackrest --stanza=mydb stanza-create

第二步:验证归档链路是否打通( 此步骤不可跳过)

sudo -u pgbackrest pgbackrest --stanza=mydb check

执行后观察输出,所有项均为 ok 才代表配置成功。如果 archive-push 报错,通常是 archive_command 中的权限问题,检查 postgres 用户是否能直接调用 pgbackrest 命令(可在 shell 中手动测试)。


4. 自动化备份策略

采用 "每周全量 + 每日差异" 策略,平衡存储空间与恢复速度。

4.1 立即执行第一次全量备份

配置完成后必须先手动执行一次全量备份! 在第一个全量备份完成之前,差异备份和 PITR 均无法工作。在等到下一个周日之前,请先手动执行:

sudo -u pgbackrest pgbackrest --stanza=mydb --type=full backup

4.2 配置 Cron 定时任务

sudo crontab -u pgbackrest -e

添加以下内容:

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:停止数据库

sudo systemctl stop postgresql

步骤 2:执行还原

restore 命令需要写入 PostgreSQL 数据目录,因此必须以 postgres 用户执行。

sudo -u postgres pgbackrest \
  --stanza=mydb \
  --type=time \
  --target="2026-03-19 14:54:59" \
  --delta \
  restore

参数说明:

参数说明
--type=time按时间点恢复
--target目标时间,替换为实际故障前的时间
--delta增量还原,仅替换有差异的文件,速度更快

步骤 3:启动数据库

sudo systemctl start postgresql

步骤 4:验证数据

psql -c "SELECT * FROM 被误删的表 LIMIT 5;"

方案二:暂停模式(不确定精确时间点时,推荐)

数据库恢复后进入只读状态,确认数据无误后再手动激活,避免时间点不准确导致的二次破坏。

步骤 1:停止数据库

sudo systemctl stop postgresql

步骤 2:执行还原(暂停模式)

sudo -u postgres pgbackrest \
  --stanza=mydb \
  --type=time \
  --target="2026-03-19 14:55:00" \
  --recovery-option=recovery_target_action=pause \
  --delta \
  restore

步骤 3:启动数据库(此时为只读)

sudo systemctl start postgresql

步骤 4:检查数据是否正确

psql -c "SELECT * FROM 被误删的表 LIMIT 5;"

步骤 5a:数据正确 → 激活数据库

SELECT pg_wal_replay_resume();

步骤 5b:数据不正确 → 重新调整时间点

# 停库
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. 注意事项

  1. 时间同步:确保服务器启用了 NTP(timedatectl status 可检查),时钟不准会导致 PITR 失败。

  2. WAL 连续性:PITR 依赖连续的 WAL 归档,切勿手动删除归档目录中的任何文件,pgBackRest 会根据保留策略自动管理。

  3. 定期恢复演练:备份的价值在于能成功恢复。建议每季度在测试环境执行一次完整的恢复演练,验证备份有效性。

  4. restore 用户:还原操作需使用 postgres 用户执行,而非 pgbackrest 用户,因为需要写入数据目录。

  5. 先做全量备份:配置完成后必须立即手动执行一次全量备份,否则自动备份任务无法正常工作。


备份的价值不在于"备",而在于"恢"。通过 pgBackRest 的 PITR 功能,您可以从容应对误删除、数据损坏等突发状况,将数据丢失风险降至最低。