pgBackRest 2.60.0 常用 CLI 命令与工具详解
pgBackRest 2.60.0 全部 21 条 CLI 命令实测详解:stanza-create/uprade/delete 三层安全门、check 体检、backup 全量/差异/增量三级备份链与自动 expire、info/verify 盘点校验、restore/delta/PITR 时间点恢复实测、stop/start 维护窗口、archive-push/get 异步归档、repo-ls/get 仓库浏览,附排障实录(WAL 归档纪律)与场景速查表;Ubuntu 22.04 + PostgreSQL 16.15 环境。
pgBackRest 2.60.0 常用 CLI 命令与工具详解
目标:把 pgBackRest 2.60.0 的命令体系一次跑通——从 stanza 创建到三级备份、从 info 盘点到 verify 校验、从标准恢复到 delta 增量恢复与 PITR 时间点恢复,再到维护窗口与仓库辅助命令,每条命令给出真实回显与踩坑记录。环境为 Ubuntu 22.04.5 LTS + PostgreSQL 16.15 + pgBackRest 2.60.0(meson 编译安装,实测日期 2026-10-19~20);安装与配置参数分别见 《Ubuntu 22.04 安装 pgBackRest 2.60.0 指南》 与 《pgBackRest 2.60.0 配置参数详解》,软件定位与选型见 《pgBackRest 2.60.0 介绍与选型指南》。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64),主机名 db1,时区 UTC(回显时间戳原样照抄)。
- 数据库:PostgreSQL 16.15,数据目录
/var/lib/postgresql/16/main,服务单元postgresql@16-main,示例库含demo表(10 万行起步)与pitr_test时间线标记表。 - pgBackRest:2.60.0,配置
/etc/pgbackrest/pgbackrest.conf,仓库 repo1=/var/lib/pgbackrest(明文 zst)、repo2=/var/lib/pgbackrest2(AES-256-CBC 加密 + bundle/block),日志/var/log/pgbackrest。 - 保留策略:repo1
repo1-retention-full=2、repo1-retention-diff=2;归档命令archive_command = 'pgbackrest --stanza=db archive-push %p'。 - 命令运行用户:
sudo -u postgres pgbackrest …(2.59.0 起 root 默认仅可运行 restore)。
二、前置条件
- pgBackRest 2.60.0 与 PostgreSQL 16 已安装(安装步骤见专栏安装篇)。
- 配置文件与 PG 归档已按《pgBackRest 2.60.0 配置参数详解》第三章就绪,仓库目录已
chown postgres:postgres。 - 理解 stanza 概念:一个 stanza 对应一个 PG 集群的备份身份,仓库中
/backup/<stanza>与/archive/<stanza>两个子树都挂在它名下。
三、命令体系总览
pgbackrest help 实测列出 2.60.0 全部 21 条命令(分组整理如下):
| 分组 | 命令 | 一句话作用 | 本文实测 |
|---|---|---|---|
| 仓库初始化 | stanza-create | 在仓库创建 stanza 元数据 | ✅ §四 |
| stanza-upgrade | 升级 stanza 元数据(PG 大版本升级/新仓库后) | ✅ §四 | |
| stanza-delete | 从仓库删除 stanza(三层安全门) | ✅ §四 | |
| 体检与备份 | check | 校验归档/备份配置端到端可用 | ✅ §五 |
| backup | 全量/差异/增量备份 | ✅ §六 | |
| 盘点校验 | info | 仓库/备份集信息(含 JSON) | ✅ §七 |
| verify | 校验仓库备份内容完整性 | ✅ §七 | |
| 恢复 | restore | 恢复备份集/PITR | ✅ §八 |
| 维护窗口 | stop / start | 暂停/恢复本 stanza 的备份与归档 | ✅ §九 |
| 归档通道 | archive-push | PG 归档 WAL 入仓(archive_command 调用) | ✅ §十 |
| archive-get | 取归档 WAL 供恢复回放(restore_command 调用) | ✅ §十 | |
| 仓库操作 | repo-ls | 浏览仓库目录 | ✅ §十 |
| repo-get / repo-put | 从/向仓库读写文件 | ✅ §十 | |
| 清理 | expire | 手动执行保留策略清理 | ✅ §十 |
| 工具自身 | version / help | 版本 / 帮助 | ✅ §三 |
| 服务端 | server / server-ping | TLS 仓库服务端进程与探活(2.58+ 引入,本文未展开) | — |
| 标注 | annotate | 给备份集追加标注元数据 | — |
标注"—"的命令本文未实测,语义以官方命令参考为准。命令通用形态:pgbackrest [选项] <命令>,常用全局选项 --stanza、--repo、--type、--set、--delta。
四、stanza 系列:stanza-create / stanza-upgrade / stanza-delete
4.1 stanza-create:给 PG 集群在仓库里立户
sudo -u postgres pgbackrest --stanza=db stanza-create
实测回显(节选):
2026-10-19 16:45:20.533 P00 INFO: stanza command begin 2.60.0: --exec-id=7821-7298f0b1 --log-level-console=info --pg1-path=/var/lib/postgresql/16/main --pg1-port=5432 --pg1-user=postgres --repo1-path=/var/lib/pgbackrest --repo1-retention-diff=2 --repo1-retention-full=2 --stanza=db
2026-10-19 16:45:21.382 P00 INFO: stanza-create command end: completed successfully (849ms)
要点:多仓库配置下,一次 stanza-create 会在所有仓库建 stanza;对已存在的仓库幂等(实测重复执行回显 stanza 'db' already exists on repo1 and is valid)。注意:该命令不支持 --repo 过滤,实测报 ERROR: [031]: option 'repo' not valid for command 'stanza-create'——给既有 stanza 新增仓库时,直接再跑一次不带 --repo 的 stanza-create 即可。
4.2 stanza-upgrade:元数据升级(幂等)
PG 大版本升级或新增仓库后刷新 stanza 元数据。实测(无需升级时):
2026-10-19 17:03:55.844 P00 INFO: stanza 'db' on repo2 is already up to date
2026-10-19 17:03:55.844 P00 INFO: stanza-upgrade command end: completed successfully (7ms)
4.3 stanza-delete:三层安全门的删除
删除 stanza 有三层前置校验,实测逐层踩过(生产排障很有代表性):
- 必须显式指定仓库:不带 --repo 报错(实测)——
2026-10-19 17:04:10.467 P00 ERROR: [037]: stanza-delete command requires option: repo
HINT: this command requires a specific repository to operate on
- stanza 必须处于 stop 状态:直接删报错(实测)——
2026-10-19 17:04:25.889 P00 ERROR: [055]: stop file does not exist for stanza 'db'
HINT: has the pgbackrest stop command been run on this server for this stanza?
- PostgreSQL 必须停库(或
--force):stop 后仍报错(实测)——
2026-10-19 17:04:41.081 P00 ERROR: [038]: postmaster.pid exists - looks like PostgreSQL is running. To delete stanza 'db' on repo1, shut down PostgreSQL for stanza 'db' and try again, or use --force.
完整正确流程实测(停库 → 逐仓删除 → 仓库清空):
sudo -u postgres pgbackrest --stanza=db stop
pg_ctlcluster 16 main stop
sudo -u postgres pgbackrest --stanza=db --repo=1 stanza-delete
sudo -u postgres pgbackrest --stanza=db --repo=2 stanza-delete
2026-10-19 17:04:53.314 P00 INFO: stanza-delete command end: completed successfully (22ms)
2026-10-19 17:05:04.040 P00 INFO: stanza-delete command end: completed successfully (3ms)
删除后 ls /var/lib/pgbackrest/backup/ /var/lib/pgbackrest/archive/ 确认子树已清空;pgbackrest --stanza=db info 回显 status: error (missing stanza path)。细节注意:repo1 删除成功会连带清掉 stop 文件,repo2 需要重新 stop 再删(实测踩中)。
五、check:归档与备份配置的端到端体检
check 会真实触发一次 WAL 切换与归档,验证"PG → archive_command → 仓库"链路和备份配置的一致性,是 stanza 建好后必跑的第一条命令:
sudo -u postgres pgbackrest --stanza=db check
实测回显(节选,可见 WAL 归档校验细节):
2026-10-19 16:45:32.759 P00 INFO: check command begin 2.60.0: --exec-id=7826-8e06b540 --archive-timeout=60 --log-level-console=info --pg1-path=/var/lib/postgresql/16/main --repo1-path=/var/lib/pgbackrest --stanza=db
2026-10-19 16:45:33.856 P01 INFO: WAL segment 000000010000000000000009 successfully archived to '/var/lib/pgbackrest/archive/db/16-1/0000000100000000/000000010000000000000009-9d85641c9057ea95667a1a01a493397094323b9.zst'
2026-10-19 16:45:34.925 P00 INFO: check command end: completed successfully (2.16s)
解读:WAL segment ... successfully archived 证明归档链路通;文件名后缀 .zst 说明归档也按 compress-type=zst 压缩入库。日常巡检可直接把 check 放进监控(报错常见于 archive_command 未生效、仓库权限不对、PG 与 stanza 的 system-id 不匹配)。
六、backup:全量/差异/增量备份
6.1 备份类型与命令
--type 三种取值(默认 full):full 全量、diff 自最近全量以来的差异、incr 自最近任意备份以来的增量。命令模板:
sudo -u postgres pgbackrest --stanza=db --type=full backup
sudo -u postgres pgbackrest --stanza=db --type=diff backup
sudo -u postgres pgbackrest --stanza=db --type=incr backup
6.2 实测:三级备份链
10 万行 demo 库上依次实测三种备份(关键回显节选):
# --type=full
2026-10-19 16:45:20.919 P00 INFO: execute exclusive pg_start_backup(): backup begins after the next regular checkpoint completes
2026-10-19 16:45:21.093 P00 INFO: backup start archive = 000000010000000000000005, lsn = 0/5000028
2026-10-19 16:45:22.020 P00 INFO: backup stop archive = 000000010000000000000005, lsn = 0/5013160
2026-10-19 16:45:22.023 P00 INFO: check archive for prior (backup label) and WAL segments
2026-10-19 16:45:23.151 P00 INFO: new backup label = 20261019-164520F
2026-10-19 16:45:23.419 P00 INFO: full backup size = 30.8MB, file total = 968
2026-10-19 16:45:23.419 P00 INFO: backup command end: completed successfully (2500ms)
# 插入 2 万行后 --type=diff
2026-10-19 16:45:31.345 P00 INFO: new backup label = 20261019-164520F_20261019-164531D
2026-10-19 16:45:31.569 P00 INFO: diff backup size = 10.4MB
# 再次小改动后 --type=incr
2026-10-19 16:45:32.585 P00 INFO: new backup label = 20261019-164520F_20261019-164532I
2026-10-19 16:45:32.635 P00 INFO: incr backup size = 8.3KB
解读三点:其一,备份标签 YYYYMMDD-HHMMSSF/D/I 中的 F/D/I 后缀即类型,_ 后接的是"基于哪个父备份";其二,check archive for prior ... and WAL segments 印证备份完成前会校验所需 WAL 已入仓(一致性模型);其三,三级链的体积梯度(30.8MB → 10.4MB → 8.3KB)直观展示了增量的价值——本次 incr 只捕获了 checkpoint 级的文件变化。
常用选项(2.60.0 实测默认值):--start-fast [default=n](立即 checkpoint)、--compress-type [default=gz]/--compress-level [default=3]、--process-max [default=1]、--online [default=y]、--resume [default=y]、--archive-check [default=y]、--archive-copy [default=n]、--expire-auto [default=y]、--backup-standby [default=n](从备库备份)、--checksum-page [default=y]。
6.3 自动 expire:与保留策略联动
配置 repo1-retention-full=2 时连做全量,第 3 个全量完成后自动清理最老链(实测回显节选):
2026-10-19 16:46:26.973 P00 INFO: new backup label = 20261019-164626F
2026-10-19 16:46:27.104 P00 INFO: expire full backup 20261019-164520F
2026-10-19 16:46:27.104 P00 INFO: expire diff backup 20261019-164520F_20261019-164613D
2026-10-19 16:46:27.104 P00 INFO: remove WAL path '/var/lib/pgbackrest/archive/db/16-1/0000000100000000'
随后 info 中只剩 20261019-164623F 与 20261019-164626F 两个全量——保留策略全自动闭环,无需手工清理。
七、info 与 verify:仓库盘点与完整性校验
7.1 info:人读格式
sudo -u postgres pgbackrest --stanza=db info
实测回显(多仓库状态一屏尽收,加密/时间线/体积全在):
stanza: db
status: mixed
repo1: ok
repo2: error (missing stanza path)
cipher: mixed
repo1: none
repo2: aes-256-cbc
db (current)
wal archive min/max (16-1): 000000010000000000000004/000000010000000000000008
full backup: 20261019-164520F
timestamp start/stop: 2026-10-19 16:45:20 / 2026-10-19 16:45:22
database size: 30.8MB, database backup size: 30.8MB
repo1: backup set size: 5.5MB backup set size: 5.5MB or 17.8% of database
常用变体:info --output=json(机器可读,含 backup label/LSN/timestamp 等全字段,可用于监控集成);info --set=<label> --output=json 看单个备份集明细;多仓库时 --repo=N 过滤。
7.2 verify:仓库内容完整性校验
verify 逐文件核对备份与归档的校验和(对加密仓库自动解密校验):
sudo -u postgres pgbackrest --stanza=db verify
实测回显(节选):
2026-10-19 16:55:26.556 P00 INFO: verify command begin 2.60.0: --exec-id=9010-0e7e05cd --log-level-console=info --process-max=4 --repo1-path=/var/lib/pgbackrest --repo2-path=/var/lib/pgbackrest2 --repo2-cipher-type=aes-256-cbc --repo2-cipher-pass=<redacted> --stanza=db
2026-10-19 16:55:27.414 P00 INFO: verify command end: completed successfully (487ms)
八、restore:标准恢复、delta 恢复与 PITR
8.1 标准恢复(整库还原)
恢复会覆盖数据目录,务必先停库。标准流程实测:
pg_ctlcluster 16 main stop
sudo -u postgres pgbackrest --stanza=db restore
pg_ctlcluster 16 main start
restore 自动选择第一个有备份的仓库的最新备份集(来源:restore 命令帮助,可用 --set=<label> 指定、--repo=N 限定仓库);写入 recovery.signal 与 postgresql.auto.conf 后,启动时回放归档 WAL 到最新。实测恢复输出(节选):
2026-10-19 16:47:39.812 P00 INFO: selected backup 20261019-164626F
... P01 INFO: selected backup ...
2026-10-19 16:47:39.908 P00 INFO: wrote /var/lib/postgresql/16/main/recovery.signal
2026-10-19 16:47:39.908 P00 INFO: wrote updated postgresql.auto.conf
restore size = 32.5MB, file total = 969
2026-10-19 16:47:39.914 P00 INFO: restore command end: completed successfully (786ms)
8.2 delta 增量恢复
不删数据目录直接 --delta,按 manifest 校验和比对后只处理变化文件(实测,数据目录中有上一轮 PITR 遗留的无效文件时):
pg_ctlcluster 16 main stop
sudo -u postgres pgbackrest --stanza=db restore --delta
2026-10-19 16:48:16.845 P00 INFO: remove invalid files/links/paths (1), backup 20261019-164626F exists and matches size ...
2026-10-19 16:48:16.853 P00 INFO: wrote /var/lib/postgresql/16/main/recovery.signal
2026-10-19 16:48:16.860 P00 INFO: wrote updated postgresql.auto.conf
restore size = 32.5MB, file total = 969
2026-10-19 16:48:16.870 P00 INFO: restore command end: completed successfully (28ms)
对比可见:文件总数相同但耗时从 786ms 降到 28ms——大库上这就是 delta 的意义(官网宣称 delta + 并行可大幅缩短恢复时间)。
8.3 PITR 时间点恢复实测(--type=time --target --target-action)
演练脚本:全量备份 → 插入标记行 row1(before-pitr,16:47:22)→ 插入 row2(after-pitr,16:47:26)→ 恢复到 16:47:25。预期:row1 在、row2 不在。
sudo -u postgres pgbackrest --stanza=db restore \
--type=time --target="2026-10-19 16:47:25+00" --target-action=promote
实测输出与恢复后验证:
2026-10-19 16:47:47.278 P00 INFO: selected backup 20261019-164626F
2026-10-19 16:47:47.292 P00 INFO: recovery will start at 2026-10-19 16:46:26
2026-10-19 16:47:47.308 P00 INFO: wrote /var/lib/postgresql/16/main/recovery.signal
2026-10-19 16:47:47.308 P00 INFO: wrote updated postgresql.auto.conf
restore size = 32.5MB, file total = 969
# 启动后验证
select pg_is_in_recovery(); -- f(已提升为主)
select id, note from pitr_test order by id;
id | note | at
----+-------------+-------------------------------
1 | before-pitr | 2026-10-19 16:47:22.312746+00
select timeline_id from pg_control_checkpoint(); -- 2(PITR 提升后时间线 +1)
语义完全符合预期:重放精确停在目标时间,row2 未出现;提升后时间线从 1 切到 2(postgresql.auto.conf 中留有 recovery_target_time/recovery_target_action='promote',均由 pgBackRest 写入)。其他 --type 取值:xid(事务号)、lsn、name、immediate、standby、default(回放到归档 WAL 尽头),time/lsn 必须配 --target(来源:restore 命令帮助)。
九、stop / start:维护窗口控制
在批量恢复、仓库迁移等场景先"挂起"本 stanza 的备份与归档,防止误触发:
sudo -u postgres pgbackrest --stanza=db stop
stop 期间备份被拒绝(实测报错):
2026-10-19 16:46:12.456 P00 ERROR: [062]: stop file exists for stanza db
结束维护后恢复(实测成功回显 start command end: completed successfully,随后备份正常执行)。注意 stop 的作用域:默认整机全部 stanza,可 --stanza=db 限定、--force 强制清 stop 文件。
十、归档与仓库辅助命令
- archive-push(由 PG 的 archive_command 自动调用):把 WAL 段推入仓库;配
--archive-async --spool-path=/var/spool/pgbackrest即异步归档,spool 的archive/db/out/*.ok为完成确认(实测见配置篇 5.8)。排障看命令回显与/var/log/pgbackrest/db-archive-push.log。 - archive-get(由 restore_command 在恢复回放时自动调用):按需取归档 WAL,支持并行与本地队列。恢复类命令无需手工调用它。
- repo-ls / repo-get / repo-put:把仓库当文件系统浏览/读取/写入。实测取备份清单头部:
sudo -u postgres pgbackrest --stanza=db repo-ls backup
sudo -u postgres pgbackrest --stanza=db repo-ls "backup/db/20261019-165412F"
sudo -u postgres pgbackrest --stanza=db repo-get "backup/db/20261019-165412F/backup.manifest" | head -6
db
backup.manifest
backup.manifest.copy
pg_data
[backrest]
backrest-format=5
backrest-version="2.60.0"
踩坑记录:repo-ls/repo-get 的路径必须是相对仓库根的相对路径,传绝对路径报错(实测)——ERROR: [096]: absolute path '/backup' is not in base path '/var/lib/pgbackrest'。
- expire(手动):
sudo -u postgres pgbackrest --stanza=db expire立即执行一次保留策略清理(关闭expire-auto或调整策略后使用);观察回显中的expire full/diff backup行确认清理范围。
十一、排障实录与场景速查
11.1 排障实录:停库前未确认归档完成,PITR 丢最新数据
现象:PITR 恢复到 row1 之后的时间点成功;随后对该"更老"的备份做 restore --delta(不带 target,预期回放到归档尽头找回 row2),结果 row2 仍未出现,且提升后时间线直接跳到 3。
定位过程:查 PG 日志发现 delta 恢复的重放在"consistent recovery state"后即结束、没有更多 WAL 可回放;再核对归档目录与 pg_stat_archiver,确认 row2 所在 WAL 段在实例停止后才完成归档(其事务提交时间 16:47:26.5 晚于 PITR 目标 16:47:25,时间线分叉后该段属于旧时间线的"分叉后追加")。
结论与纪律(生产必须执行):
- 任何停库/清目录/恢复前,先确保 WAL 全部归档:连续执行两次
select pg_switch_wal();,或核对select last_archived_wal from pg_stat_archiver;覆盖当前写入位置,再跑pgbackrest --stanza=db check兜底。 - PITR 提升后立即做一次新的全量备份(官方推荐实践):避免后续备份/恢复在时间线分叉上做二次推理。
- 需要找回"分叉点之后旧时间线"的数据时,用
--target-timeline=1(或对应历史)显式指定旧时间线,并配合--set选择合适的备份集。
11.2 场景 → 命令速查表
| 场景 | 命令 |
|---|---|
| 新集群接入备份 | stanza-create → check → --type=full backup |
| 日常巡检 | check、info、verify |
| 计划内每日备份 | --type=diff backup(systemd timer/cron 调度) |
| 数据误删,恢复到误删前 1 分钟 | 停库 → restore --type=time --target="…" --target-action=promote → 起库验证 |
| 整库快速搬迁 | 停目标库 → restore(或 --delta 复用旧目录)→ 起库 |
| 大库只想恢复某个库 | restore --db-include=appdb |
| 升级 PG 大版本后 | stanza-upgrade → check → --type=full backup |
| 仓库迁移/退役 | stop → 停库 → --repo=N stanza-delete → 清目录 |
| 只读仓库文件 | repo-ls / repo-get |
十二、FAQ
Q1:backup 报 [062]: stop file exists for stanza db?
维护模式还开着(实测复现路径见 §九)。pgbackrest --stanza=db start 即恢复;确认无人正在做批量恢复再 start。
Q2:stanza-delete 一路报错?
按三层安全门顺序排查(§4.3 实测):缺 --repo 报 [037] → 未 stop 报 [055] → 未停库报 [038];要么补齐前置条件,要么 --force(自担风险)。
Q3:restore 后起库报 recovery 相关错误?
先看 /var/lib/postgresql/16/main/postgresql.auto.conf 的 restore_command/recovery_target 是否符合预期(restore 会重写该文件),再用 pgbackrest info 核对归档 min/max 是否覆盖恢复窗口;必要时 --archive-mode=off 做隔离演练(避免恢复实例把 WAL 推回生产仓库)。
Q4:备份体积与 info 显示不一致?
database size 是数据目录逻辑大小,backup set size 是仓库侧压缩后的实际占用(实测 30.8MB → 5.5MB,zst 17.8%);增量备份的 database backup size 是该集自身增量体积,恢复时仍引用全量链(见 info 的 backup reference 字段)。
Q5:加密仓库的密码会出现在日志里吗?
不会,实测回显统一脱敏为 --repo2-cipher-pass=<redacted>;但注意 repo-ls/repo-get 能读仓库文件,应控制可运行 pgbackrest 的账号范围。
Q6:check 通过但 backup 报归档超时?
archive-timeout [default=1m] 内 WAL 没入仓:看归档日志与 spool 队列(异步模式),高写入量库可调大 archive-timeout 或启用 --archive-async,并评估 archive-push-queue-max。
十三、参考链接
- 官方命令参考(21 条命令权威说明):https://pgbackrest.org/command.html
- 官方用户指南(备份/恢复演练):https://pgbackrest.org/user-guide.html
- 2.60.0 发行说明:https://github.com/pgbackrest/pgbackrest/releases/tag/release/2.60.0
- 站内相关:《pgBackRest 2.60.0 介绍与选型指南》、《Ubuntu 22.04 安装 pgBackRest 2.60.0 指南》、《pgBackRest 2.60.0 配置参数详解》、《PostgreSQL 18 常用 CLI 命令与工具详解》