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 环境。

pgBackRestPostgreSQL备份恢复2026/10/20

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-pushPG 归档 WAL 入仓(archive_command 调用)✅ §十
archive-get取归档 WAL 供恢复回放(restore_command 调用)✅ §十
仓库操作repo-ls浏览仓库目录✅ §十
repo-get / repo-put从/向仓库读写文件✅ §十
清理expire手动执行保留策略清理✅ §十
工具自身version / help版本 / 帮助✅ §三
服务端server / server-pingTLS 仓库服务端进程与探活(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 有三层前置校验,实测逐层踩过(生产排障很有代表性):

  1. 必须显式指定仓库:不带 --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
  1. 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?
  1. 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,时间线分叉后该段属于旧时间线的"分叉后追加")。

结论与纪律(生产必须执行):

  1. 任何停库/清目录/恢复前,先确保 WAL 全部归档:连续执行两次 select pg_switch_wal();,或核对 select last_archived_wal from pg_stat_archiver; 覆盖当前写入位置,再跑 pgbackrest --stanza=db check 兜底。
  2. PITR 提升后立即做一次新的全量备份(官方推荐实践):避免后续备份/恢复在时间线分叉上做二次推理。
  3. 需要找回"分叉点之后旧时间线"的数据时,用 --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。

十三、参考链接