这是本节的多页打印视图。
点击此处打印 .
返回本页常规视图 .
备份恢复 配置备份策略与备份仓库,管理备份,执行时间点恢复:pgBackRest 引擎与 Pigsty 封装层的完整实操手册。
Pigsty 使用 pgBackRest 管理 PostgreSQL 备份 —— 这可能是 PostgreSQL 生态中最强大的开源备份工具,
支持增量备份、并行处理、加密、MinIO /S3 对象存储等众多特性。
每个 PGSQL 集群默认都预配置了备份与 WAL 归档,开箱即用。
本章是备份恢复的 实操手册 :配置方法、管理命令、恢复操作与演练教程。
设计理念与心智模型(为什么、如何权衡)请参阅概念层文档 时间点恢复 。
所有的备份恢复操作,最终都会落实为 pgBackRest 命令。Pigsty 在它之上提供了三层封装,按需选用:
层次 接口 形态 适用场景 集群编排 pg_pitr 参数 + pgsql-pitr.yml 剧本Ansible 剧本 生产集群恢复:编排 HA、etcd 与多节点 实例编排 pig pitr命令行工具 单节点恢复:在数据库节点上直接编排执行 命令原语 pig pb / pb 别名 / pg-backup 脚本pgBackRest 封装 备份、查询、清理,以及非托管实例的裸恢复 底层引擎 pgbackrest原生命令 一切封装的最终执行者
章节 内容 机制 pgBackRest 核心概念(stanza / 仓库 / 保留 / 时间线)与 Pigsty 的封装映射 策略 设计备份策略:调度计划、恢复窗口与磁盘空间规划 仓库 配置备份仓库:本地、MinIO、S3,加密、版本控制与锁定 管理 备份管理命令手册:启停、手动备份、查看、清理、Stanza 管理 恢复 执行时间点恢复:恢复目标、分步执行、参数参考 克隆 用 PITR 克隆数据库集群:找回数据、恢复演练 示例 沙箱教程:使用 pgBackRest 原语手工执行恢复
免责声明
Pigsty 尽最大努力提供可靠的 PITR 解决方案,但我们不对 PITR 操作导致的数据丢失承担任何责任,使用需自担风险。如需专业支持,请考虑我们的 专业服务 。
快速上手 设计备份策略 :用 pg_crontab 声明定时备份计划,用 pgbackrest_repo 选择备份仓库管理备份 :用 pg-backup 手动备份,用 pb info 查看备份状态执行恢复 :用 pg_pitr 参数声明恢复目标,运行 pgsql-pitr.yml 剧本pg_crontab : [ '00 01 * * * /pg/bin/pg-backup full' ]
./pgsql-pitr.yml -l pg-meta -e '{"pg_pitr": { "time": "2025-07-13 10:00:00+00", "action": "promote" }}'
1 - 备份机制 pgBackRest 的概念体系(stanza、仓库、备份链、保留策略、时间线)与 Pigsty 封装层的参数映射:理解每条命令背后发生了什么。
Pigsty 的备份恢复功能,最终都会落实为 pgBackRest 命令的执行。
所以要真正掌握这套系统,需要理解两件事:pgBackRest 本身的概念体系 (stanza、仓库、备份链、保留、时间线),
以及 Pigsty 各层封装如何映射到它 (参数如何变成命令行选项)。本页依次讲清这两部分。
pgBackRest 核心概念 Stanza:集群的备份身份 Stanza (节)是 pgBackRest 中一套 PostgreSQL 集群备份配置的名称,也是仓库内隔离不同集群的命名空间。
Pigsty 将 stanza 直接映射为集群名 pg_cluster :
集群 pg-meta 的备份就存储在仓库的 backup/pg-meta/ 与 archive/pg-meta/ 目录下,
多套集群可以安全共享同一个仓库。
Stanza 记录着源集群的 system-id 与主版本号,写入备份前会核对身份 —— 这正是
克隆集群 后需要 stanza-upgrade 善后的原因。
Stanza 由 stanza-create 创建(Pigsty 在集群初始化时自动完成),
版本升级后用 stanza-upgrade 更新。
仓库:备份存放在哪里 仓库 (Repository)是备份与 WAL 归档的存储后端,在配置中以 repo1-* 系列选项定义:
repo1-type 决定类型(POSIX 文件系统、S3、Azure、GCS、SFTP),repo1-path 决定路径,
repo1-cipher-* 决定加密,repo1-retention-* 决定保留策略。
Pigsty 通过 pgbackrest_repo 参数生成这些配置,详见 备份仓库 。
备份链与备份标签 pgBackRest 支持三种备份类型,后两种依赖前面的备份构成 备份链 :
类型 内容 标签后缀 全量备份(full) 完整复制数据库集群 F差异备份(diff) 相对最近一次 全量 的变化 D增量备份(incr) 相对最近一次 任意备份 的变化 I
每个备份都有唯一的 备份标签 (label),命名规则本身就描述了备份链:
20250715-013657F 是一个全量备份,20250715-013657F_20250715-013724D 是基于它的差异备份,
20250715-013657F_20250715-013730I 是增量备份 —— 下划线前的部分标识它所依附的全量备份。
恢复时用 --set 指定从哪个备份集开始还原,默认自动选择目标时间点前最近的一个。
保留策略:仓库如何不被撑爆 保留策略 (Retention)决定旧备份何时被清除。repo1-retention-full 配合
repo1-retention-full-type(count 按份数 / time 按天数)控制全量备份的保留;
全量备份过期时,依附它的差异/增量备份与对应的 WAL 归档一并清除。
Pigsty 默认启用 expire-auto,每次备份完成后自动执行过期清理,也可用
expire 命令手动触发。
time 表示 最短时间窗口 ,不是“只保留最近 N 天内的全量备份”。只有在仓库中还存在另一份年龄达到 N 天的全量备份时,
更老的全量备份才会过期。因此 retention_full: 14 配合每周全备,稳态会保留三条全量备份链,恢复窗口约为 14~21 天。
WAL 归档:保留下来的历史 PostgreSQL 的 archive_command 在每个 WAL 段写满(或 archive_timeout 超时)后触发,
Pigsty 将其配置为 archive-push ,把 WAL 推入仓库;
恢复时则由 restore_command 调用 archive-get 按需拉取。
Pigsty 启用了异步归档(archive-async=y),经由 /pg/spool 假脱机目录批量推送,避免归档拖慢主库。
时间线:分叉的历史 每次恢复提升(或故障切换)都会开启一条新的 时间线 (Timeline),旧时间线的 WAL 仍保留在仓库中。
恢复时可用 --target-timeline 指定沿哪条时间线重放(默认 latest),
这使得"恢复错了再恢复一次"成为可能。完整心智模型见概念层 工作原理 。
恢复机制:restore 命令做了什么 理解 restore 命令的行为,就理解了 PITR 的执行过程。它做两件事:
重建数据目录 :从备份集还原数据文件。带 --delta 选项(Pigsty 默认启用)时执行增量还原 ——
校验现有文件,只重写与备份不一致的部分,大幅缩短大库的还原时间。写入恢复配置 :生成 recovery.signal 标记与恢复参数(restore_command、recovery_target_*),
使 PostgreSQL 下次启动时进入恢复模式,从仓库拉取 WAL 重放至目标点。因此 restore 命令返回成功只是完成了一半:真正的恢复发生在 PostgreSQL 启动之后的 WAL 重放阶段。
重放到达目标后的行为由 --target-action 决定:pause 暂停等待检查、promote 提升开启新时间线、shutdown 停机。
恢复目标的参数组合是固定句式:--type 指定目标类型,--target 给出目标值,
可选的 --target-exclusive 控制边界、--target-timeline 选择时间线、--set 指定起点备份:
pgbackrest --stanza= pg-meta restore # 恢复到 WAL 归档末尾
pgbackrest --stanza= pg-meta --type= immediate restore # 恢复到最近一致点
pgbackrest --stanza= pg-meta --type= time --target= '2025-07-13 10:00:00+00' restore
pgbackrest --stanza= pg-meta --type= xid --target= '250000' --target-exclusive restore
pgbackrest --stanza= pg-meta --type= name --target= 'my-restore-point' restore
pgbackrest --stanza= pg-meta --type= lsn --target= '0/4001C80' --target-action= promote restore
实际观察 您可以使用 pg_dbsu 用户(默认 postgres)直接执行 pgbackrest 命令,
观察上述概念的实际形态 —— 注意备份标签的命名、备份大小的差异,以及 info 输出中的备份链引用关系:
$ pgbackrest --stanza= pg-meta --type= full backup
2025-07-15 01:36:57.007 P00 INFO: backup command begin 2.54.2: --annotation= pg_cluster = pg-meta ...
2025-07-15 01:36:57.030 P00 INFO: execute non-exclusive backup start: backup begins after the requested immediate checkpoint completes
2025-07-15 01:36:57.105 P00 INFO: backup start archive = 000000010000000000000006, lsn = 0/6000028
2025-07-15 01:36:58.540 P00 INFO: new backup label = 20250715-013657F
2025-07-15 01:36:58.588 P00 INFO: full backup size = 44.5MB, file total = 1437
2025-07-15 01:36:58.589 P00 INFO: backup command end: completed successfully ( 1584ms) $ pgbackrest --stanza= pg-meta --type= diff backup
2025-07-15 01:37:24.952 P00 INFO: backup command begin 2.54.2: ...
2025-07-15 01:37:24.985 P00 INFO: last backup label = 20250715-013657F, version = 2.54.2
2025-07-15 01:37:26.337 P00 INFO: new backup label = 20250715-013657F_20250715-013724D
2025-07-15 01:37:26.381 P00 INFO: diff backup size = 424.3KB, file total = 1437
2025-07-15 01:37:26.381 P00 INFO: backup command end: completed successfully ( 1431ms) $ pgbackrest --stanza= pg-meta --type= incr backup
2025-07-15 01:37:30.305 P00 INFO: backup command begin 2.54.2: ...
2025-07-15 01:37:30.337 P00 INFO: last backup label = 20250715-013657F_20250715-013724D, version = 2.54.2
2025-07-15 01:37:31.356 P00 INFO: new backup label = 20250715-013657F_20250715-013730I
2025-07-15 01:37:31.403 P00 INFO: incr backup size = 8.3KB, file total = 1437
2025-07-15 01:37:31.403 P00 INFO: backup command end: completed successfully ( 1099ms) $ pgbackrest --stanza= pg-meta info
stanza: pg-meta
status: ok
cipher: aes-256-cbc
db ( current)
wal archive min/max ( 17) : 000000010000000000000001/00000001000000000000000A
full backup: 20250715-013657F
timestamp start/stop: 2025-07-15 01:36:57+00 / 2025-07-15 01:36:58+00
wal start/stop: 000000010000000000000006 / 000000010000000000000006
database size: 44.5MB, database backup size: 44.5MB
repo1: backup size: 8.7MB
diff backup: 20250715-013657F_20250715-013724D
timestamp start/stop: 2025-07-15 01:37:24+00 / 2025-07-15 01:37:26+00
database size: 44.5MB, database backup size: 424.3KB
repo1: backup size: 94KB
backup reference total: 1 full
incr backup: 20250715-013657F_20250715-013730I
timestamp start/stop: 2025-07-15 01:37:30+00 / 2025-07-15 01:37:31+00
database size: 44.5MB, database backup size: 8.3KB
repo1: backup size: 504B
backup reference total: 1 full, 1 diff Pigsty 的封装层次 在原生命令之上,Pigsty 提供了逐层升高的封装,每一层都只是对下一层的参数化调用,没有黑魔法:
层次 接口 它实际做什么 集群编排 pg_pitr + pgsql-pitr.yml编排整个集群的恢复:暂停 HA → 停库 → 渲染配置并调用 pgbackrest restore → 输出控制信息 → 清理 etcd → 拉起 HA 实例编排 pig pitr单节点编排:预检 → 停 Patroni/PG → 调用 pgbackrest restore → 可选启动 PG,Patroni 保持停止 命令原语 pig pb / pb 别名 / pg-backup自动填充 --stanza 与 DBSU 身份,转发给 pgbackrest 对应子命令 底层引擎 pgbackrest读取 /etc/pgbackrest/pgbackrest.conf,实际执行备份/归档/恢复
命令原语层 pb 是登录 shell 内置的别名函数:从配置文件解析出 stanza 后转发,让您少敲一个参数:
function pb() {
local stanza = $( grep -o '\[[^][]*]' /etc/pgbackrest/pgbackrest.conf | head -n1 | sed 's/.*\[\([^]]*\)].*/\1/' )
pgbackrest --stanza= $stanza $@
}
pb info # = pgbackrest --stanza=pg-meta info
pb backup # = pgbackrest --stanza=pg-meta backup
pg-backup 脚本在此基础上增加了 角色检查 (只在主库执行,从库直接退出),供 crontab 安全调用:
pg-backup full # = pgbackrest --stanza=pg-meta --type=full backup(仅主库执行)
pg-backup diff # = pgbackrest --stanza=pg-meta --type=diff backup
pg-backup incr # = pgbackrest --stanza=pg-meta --type=incr backup(默认,无全量时自动升级为全量)
pig pb 提供了更完善的封装:自动检测 stanza、自动以 DBSU 身份执行(root 下 su、普通用户 sudo)、
备份前检查主库角色、恢复前显示执行计划并要求确认。完整子命令表见 管理命令 。
参数如何映射 Pigsty 恢复接口的每个参数,都对应一个 pgbackrest 选项 —— 三层接口共用同一套语义:
pg_pitr 字段pig pitr 选项pgbackrest 选项 含义 cluster--stanza--stanza从哪个集群的备份恢复(源 stanza) type + time/xid/lsn/name--time/--xid/--lsn/--name--type + --target恢复目标 (type: default) --default不传 --type/--target 重放到 WAL 归档末尾 (type: immediate) --immediate--type=immediate恢复到最近一致点 exclusive--exclusive / -X--target-exclusive停在目标之前(排除目标点) action--target-action--target-action到达目标后:pause / promote / shutdown timeline--target-timeline / -T--target-timeline目标时间线,默认 latest set--set / -b--set从哪个备份集开始还原 db_include / db_exclude— --db-include / --db-exclude选择性恢复部分数据库 link_map— --link-map表空间/目录软链接映射 process— process-max恢复并行进程数 data--data / -D--pg1-path恢复到哪个数据目录 repo— repo1-*(渲染临时配置)覆盖备份仓库定义;pig pitr --repo 仅选择现有配置中的仓库编号
选择性恢复仍是物理恢复:未包含或被排除的数据库会以稀疏清零文件还原,以便 PostgreSQL 完成恢复,但这些数据库本身不可访问,
恢复后需要显式删除。它不是 pg_dump 那样的逻辑子集恢复。
配置如何渲染 pgbackrest_repo 中被 pgbackrest_method
选中的仓库定义,会按简单规则渲染进 /etc/pgbackrest/pgbackrest.conf:
键名的下划线替换为连字符,加上 repo1- 前缀 —— 因此 pgBackRest 支持的仓库级配置项
可以直接写入参数:
pgbackrest_repo :
minio :
type : s3 # ----> repo1-type=s3
s3_endpoint : sss.pigsty # ----> repo1-s3-endpoint=sss.pigsty
cipher_type : aes-256-cbc # ----> repo1-cipher-type=aes-256-cbc
retention_full : 14 # ----> repo1-retention-full=14
执行 pgsql-pitr.yml 时,Pigsty 会另行渲染一份临时配置 /pg/conf/pitr.conf(避免污染常规配置),
该剧本启动恢复期间的 PostgreSQL 日志写入 /pg/tmp/recovery.log。
定时备份 Pigsty 使用 Linux crontab 调度备份任务:pg_crontab 参数中的条目
会写入 postgres 用户的 crontab。因为 pg-backup 自带角色检查,同一份 crontab 可以下发到集群所有节点 ——
故障切换后,新主库会自动接续后续定时备份。
pg_crontab : [ '00 01 * * * /pg/bin/pg-backup full' ]
pg_crontab :
- '00 01 * * 1 /pg/bin/pg-backup full'
- '00 01 * * 2,3,4,5,6,7 /pg/bin/pg-backup'
修改后用剧本应用变更:
./pgsql.yml -t pg_crontab -l pg-meta # 更新 pg-meta 集群的 crontab
如何选择备份频率与保留策略,请参阅 备份策略 。
部署细节 pgBackRest 组件在 pgsql.yml 剧本中完成安装与配置:
文件层次 路径 用途 /usr/bin/pgbackrest二进制,来自 PGDG 仓库的 pgbackrest 包 /etc/pgbackrest/pgbackrest.conf主配置文件(stanza + 仓库定义) /pg/backup本地仓库数据目录(local 仓库时使用) /pg/spool异步归档的假脱机目录 /pg/log/pgbackrest/备份/归档/恢复日志,pgbackrest_log_dir /pg/conf/pitr.confPITR 过程中的临时 pgbackrest 配置 /pg/tmp/recovery.logPITR 过程中的 PostgreSQL 恢复日志
监控 每个节点运行 pgbackrest_exporter 服务(端口 pgbackrest_exporter_port :9854),
将备份状态导出为监控指标(参见 pgBackRest 监控指标 )。
可通过 pgbackrest_exporter_options 定制,
或将 pgbackrest_exporter_enabled 设为 false 禁用。
2 - 备份策略 设计并配置备份策略:备份频率决定恢复速度,保留策略决定恢复窗口与空间占用,两张推演图帮您做出量化决策。
备份策略要回答三个问题:何时 备份(调度计划)、何处 存放(备份仓库 )、
保留多久 (保留策略)。本页给出两套久经考验的预设策略及其量化推演 ——
背后的权衡逻辑请参阅概念层文档 策略权衡 。
备份频率与恢复速度直接相关:恢复时需要从最近的基础备份开始重放 WAL 日志到目标时间点,
备份越频繁,需要重放的 WAL 越少,恢复越快;而保留策略与仓库空间直接相关:窗口越长,占用空间越大。
每日全量备份 对于生产数据库,建议从最简单的每日全量备份策略开始。Pigsty 随附的标准 pigsty.yml 集群示例采用这一策略,
配合默认的 local 本地仓库(保留最近 2 个全量备份)使用:
pg_crontab : [ '00 01 * * * /pg/bin/pg-backup full' ]
pgbackrest_method : local # 选择备份仓库方法:`local`、`minio` 或其他自定义仓库
pgbackrest_repo : # pgbackrest 仓库配置: https://pgbackrest.org/configuration.html#section-repository
local : # 使用本地 POSIX 文件系统的默认 pgbackrest 仓库
path : /pg/backup # 本地备份目录,默认为 `/pg/backup`
retention_full_type : count # 按数量保留全量备份
retention_full : 2 # 使用本地文件系统仓库时,保留2个,最多3个全量备份
假设您的数据库大小为 100GB,每天写入 10GB 数据,备份耗时 1 小时。
下图将「恢复窗口」与「存储空间占用」合并到同一时间轴(0~108h)上推演该策略的稳态行为:
恢复窗口在 24~48 小时 之间循环,备份占用约为 2 个全量备份加上 1~2 天的 WAL 归档。
在实践中,您需要准备至少 3~5 倍 数据库大小的备份磁盘,才能从容使用该默认策略。
全量 + 增量备份 如果使用 MinIO / S3 作为集中式备份仓库,存储空间不再受本地磁盘限制,
此时可以用「周全量 + 每日增量」配合两周保留策略,换取更长的恢复窗口:
pg_crontab : # 周一凌晨1点全量备份,其余每日增量备份
- '00 01 * * 1 /pg/bin/pg-backup full'
- '00 01 * * 2,3,4,5,6,7 /pg/bin/pg-backup'
pgbackrest_method : minio
pgbackrest_repo : # pgbackrest 仓库配置: https://pgbackrest.org/configuration.html#section-repository
minio : # 可选的 minio 仓库
type : s3 # minio 兼容 S3 协议
s3_endpoint : sss.pigsty # minio 端点域名,默认为 `sss.pigsty`
s3_region : us-east-1 # minio 区域,默认 us-east-1,对 minio 无实际意义
s3_bucket : pgsql # minio 桶名,默认为 `pgsql`
s3_key : pgbackrest # pgbackrest 的 minio 用户访问密钥
s3_key_secret : S3User.Backup # MinIO 用户密钥
s3_uri_style : path # minio 使用路径风格 URI 而非主机风格
path : /pgbackrest # minio 备份路径,默认为 `/pgbackrest`
storage_port : 9000 # minio 端口,默认 9000
storage_ca_file : /etc/pki/ca.crt # minio CA 证书路径,默认 `/etc/pki/ca.crt`
block : y # 启用块级增量备份
bundle : y # 将小文件打包成单个文件
bundle_limit : 20MiB # 文件包大小限制,对象存储建议 20MiB
bundle_size : 128MiB # 文件包目标大小,对象存储建议 128MiB
cipher_type : aes-256-cbc # 为远程备份仓库启用 AES 加密
cipher_pass : pgBackRest # 仓库加密密码
retention_full_type : time # 按时间保留全量备份
retention_full : 14 # 按时间保留 14 天
同样假设数据库 100GB、每日增量与 WAL 均按 10GB 粗估,下图推演 30 天内恢复窗口与存储占用的变化:
retention_full_type: time 会确保至少留下一份年龄达到 14 天的全量备份,周全备时恢复窗口在 14~21 天 之间循环。
按这组未压缩假设,稳态占用约为 560~690GB,新全量完成、旧链过期前的瞬时峰值约为 790GB;
实际占用取决于 WAL 量、块级增量命中率与 zstd 压缩率。
空间规划 两套策略的空间需求可以按以下经验公式粗估(实际占用受压缩与块级增量影响,通常更低):
策略 恢复窗口 空间粗估 建议预留 每日全量,保留 2 份(local) 24~48 小时 2 × 全量 + 1~2 天 WAL 数据库大小的 3~5 倍 周全量 + 日增量,按时间保留 14 天(minio) 14~21 天 3 × 全量 + 12~18 份增量 + 14~21 天 WAL 按实测压缩率与 WAL 量规划
注意 瞬时峰值 :新的全量备份成功完成后,旧备份才会参与过期计算,因此仓库会短暂多出一份全量备份,
同时保留尚未清理的旧备份链与 WAL。空间规划必须覆盖这个峰值而非只看清理后的稳态。
WAL 归档的增长与写入负载成正比。批量导数、VACUUM FULL、大规模 UPDATE 都会瞬间产生大量 WAL,
如果备份仓库空间紧张,请在此类操作前后关注仓库水位(监控指标 开箱即用)。
应用策略变更 备份策略的三类变更,分别用对应的剧本任务应用:
./pgsql.yml -t pg_crontab -l pg-meta # 变更调度计划(pg_crontab)后:更新 crontab
./pgsql.yml -t pg_backup -l pg-meta # 变更仓库定义(pgbackrest_repo / pgbackrest_method)后:重新渲染配置并初始化 stanza
pg-backup full # 切换仓库后:立即执行一次全量备份,建立新仓库中的恢复起点
注意:切换 pgbackrest_method 到新仓库后,旧仓库中的备份不会自动迁移;
在新仓库完成首次全量备份之前,恢复窗口存在缺口。
3 - 备份仓库 配置备份存储仓库:本地磁盘、MinIO 与 S3 对象存储,保留策略、加密、版本控制与对象锁定。
备份存储在哪里,由两个参数决定:pgbackrest_repo 定义所有候选仓库,
pgbackrest_method 选择实际使用哪一个。
仓库定义中的键值会 按固定规则 渲染为 pgbackrest 的 repo1-* 配置项,
因此 pgBackRest 支持的任何仓库选项 都可以直接写入。
默认仓库 Pigsty 预置了两个仓库定义:local 与 minio。
local:默认选项 ,使用本地 /pg/backup 目录(软链接指向 pg_fs_backup :/data/backups)minio:使用专用 MinIO 集群或任意 S3 兼容对象存储(Pigsty 支持,默认不启用)pgbackrest_method : local # 选择备份仓库方法:`local`、`minio` 或其他自定义仓库
pgbackrest_repo : # pgbackrest 仓库配置: https://pgbackrest.org/configuration.html#section-repository
local : # 使用本地 POSIX 文件系统的默认 pgbackrest 仓库
path : /pg/backup # 本地备份目录,默认为 `/pg/backup`
retention_full_type : count # 按数量保留全量备份
retention_full : 2 # 使用本地文件系统仓库时,保留2个,最多3个全量备份
minio : # 可选的 minio 仓库
type : s3 # minio 兼容 S3 协议
s3_endpoint : sss.pigsty # minio 端点域名,默认为 `sss.pigsty`
s3_region : us-east-1 # minio 区域,默认 us-east-1,对 minio 无实际意义
s3_bucket : pgsql # minio 桶名,默认为 `pgsql`
s3_key : pgbackrest # pgbackrest 的 minio 用户访问密钥
s3_key_secret : S3User.Backup # pgbackrest 的 minio 用户密钥
s3_uri_style : path # minio 使用路径风格 URI 而非主机风格
path : /pgbackrest # minio 备份路径,默认为 `/pgbackrest`
storage_port : 9000 # minio 端口,默认 9000
storage_ca_file : /etc/pki/ca.crt # minio CA 证书路径,默认 `/etc/pki/ca.crt`
block : y # 启用块级增量备份
bundle : y # 将小文件打包成单个文件
bundle_limit : 20MiB # 文件包大小限制,对象存储建议 20MiB
bundle_size : 128MiB # 文件包目标大小,对象存储建议 128MiB
cipher_type : aes-256-cbc # 为远程备份仓库启用 AES 加密
cipher_pass : pgBackRest # AES 加密密码,默认为 'pgBackRest'
retention_full_type : time # 按时间保留全量备份
retention_full : 14 # 按时间保留 14 天
两套仓库的预置策略有意不同:local 不加密、不打包、按份数保留,追求简单与恢复速度;
minio 加密(AES-256-CBC)、打包(bundle)、块级增量(block)、按时间保留两周,面向生产容灾。
生产环境请修改默认密码
使用远程仓库时,请务必修改默认的 cipher_pass 加密密码与 s3_key_secret 访问密钥。
示例中的 pgBackRest 与 S3User.Backup 是公开默认值,不能直接用于生产环境。
加密密码一旦遗失,仓库中的备份将无法解密恢复 —— 请与备份分开妥善保管,具体要求参阅 部署安全 。
保留策略 如果只备份不清理,仓库迟早被撑爆。保留策略在仓库定义中声明,由 pgBackRest 在每次备份后自动执行清理
(全量备份过期时,依附它的差异/增量备份与对应 WAL 归档一并清除):
retention_full_type: count + retention_full: 2:按份数保留 —— 保留最近 2 个全量备份(新备份完成前短暂存在第 3 个)retention_full_type: time + retention_full: 14:按时间保留 —— 至少留下一份年龄达到 14 天的全量备份后,才会删除更老的备份保留策略与恢复窗口、空间占用的量化关系,请参阅 备份策略 ;
手动清理过期备份的方法,请参阅 管理命令 。
使用 MinIO 仓库 MinIO 是 Pigsty 内置支持的 S3 兼容对象存储,作为集中备份仓库使用时,
为备份提供独立于数据库主机的故障域。启用方式:部署 MinIO 集群,然后将备份方法切换为 minio:
all :
vars :
pgbackrest_method : minio # 使用 minio 作为默认备份仓库
children : # 定义一个单节点 minio SNSD 集群
minio : { hosts : { 10.10.10.10 : { minio_seq : 1 }} ,vars : { minio_cluster : minio }}
Pigsty 的 MinIO 仓库预设通过域名(默认 sss.pigsty)和 HTTPS 端点访问对象存储,
并使用自签名 CA(/etc/pki/ca.crt)验证这条链路。
默认的 pgsql 桶与 pgbackrest 访问用户在 MinIO 集群初始化时自动创建。
对于严肃的生产部署,建议使用多节点 MinIO 集群(MNMD,纠删码容错),参阅 MinIO 配置 。
使用 S3 / 云对象存储 如果您只有一个节点,最有意义的备份策略就是使用云厂商的对象存储服务(AWS S3、阿里云 OSS 等),
以极低的成本获得异地容灾能力。定义一个新仓库并切换过去即可:
pgbackrest_method : s3 # 使用 'pgbackrest_repo.s3' 作为备份仓库
pgbackrest_repo : # pgbackrest 仓库配置: https://pgbackrest.org/configuration.html#section-repository
s3 : # 阿里云 OSS(S3 兼容)对象存储服务示例
type : s3 # oss 兼容 S3 协议
s3_endpoint : oss-cn-beijing-internal.aliyuncs.com
s3_region : oss-cn-beijing
s3_bucket : <your_bucket_name>
s3_key : <your_access_key>
s3_key_secret : <your_secret_key>
s3_uri_style : host # 云厂商对象存储通常使用主机风格 URI
path : /pgbackrest
bundle : y # 将小文件打包成单个文件
bundle_limit : 20MiB # 文件包大小限制,对象存储建议 20MiB
bundle_size : 128MiB # 文件包目标大小,对象存储建议 128MiB
cipher_type : aes-256-cbc # 为远程备份仓库启用 AES 加密
cipher_pass : pgBackRest # AES 加密密码
retention_full_type : time # 按时间保留全量备份
retention_full : 14 # 按时间保留 14 天
local : # 保留默认本地仓库定义,便于随时切换
path : /pg/backup
retention_full_type : count
retention_full : 2
除 S3 兼容存储外,pgBackRest 还支持以下后端,配置方式参阅官方用户指南:
多集群共享仓库 一个集中式仓库可以同时服务多套 PostgreSQL 集群:pgBackRest 用 stanza
(即 pg_cluster )隔离各集群的备份与归档,互不干扰。
这也是 克隆集群 的基础 —— 新集群可以直接从共享仓库中读取源集群的备份进行恢复。
因此,请确保同一仓库下的集群名称 全局唯一 ,即使它们分属不同的部署环境。
仓库版本控制 对象存储的 版本控制 (Versioning)为仓库提供同一存储系统内的版本保护:即使备份文件被覆盖或删除,历史版本仍有机会找回。
它与当前仓库共享同一故障域和管理平面,不能替代独立的异地或离线副本。
您可以在 minio_buckets 中为桶添加 versioning 标志启用:
minio_buckets :
- { name : pgsql ,versioning : true }
- { name : meta ,versioning : true }
- { name : data }
配合 pgBackRest 的 repo-target-time 选项,
甚至可以把整个仓库"回滚"到过去某一时刻的状态读取 —— 相当于对备份系统本身做时间点恢复。
仓库锁定 部分对象存储(S3、MinIO 等)支持 对象锁定 (Object Lock / WORM):对对象版本配置保留模式与期限后,
锁定版本在保留期内不可修改、不可永久删除。这是对抗勒索攻击的重要防线,但普通删除仍可能写入 Delete Marker,
暂时隐藏当前对象;恢复时需要保留版本与版本管理能力。
在 minio_buckets 中添加 lock 标志,只会在创建桶时启用对象锁定能力与版本控制:
minio_buckets :
- { name : pgsql ,lock : true }
- { name : meta ,versioning : true }
- { name : data }
这一步还没有给新对象设置 WORM 保留期。您还需要在 MinIO 中使用 mcli retention set 或控制台配置默认的
GOVERNANCE / COMPLIANCE 模式与期限,并用 mcli retention info 验证。GOVERNANCE 可以被拥有 bypass 权限的主体绕过;
COMPLIANCE 在期限内连 root 用户也不能解除。
锁定会改变 过期清理 与 移除集群备份
的行为:pgBackRest 可以让对象在逻辑上过期,但被锁定的历史版本仍会占用空间,直到保留期结束。上线前应在测试桶中验证
备份、expire、删除标记清理和版本恢复的完整流程。
切换仓库 变更仓库定义或切换 pgbackrest_method 后,需要重新渲染配置、初始化 stanza,并尽快建立新仓库中的恢复起点:
./pgsql.yml -t pg_backup -l pg-meta # 重新配置 pgbackrest 并创建 stanza
pg-backup full # 立即执行全量备份,建立新仓库中的第一个恢复点
旧仓库中的备份不会自动迁移,但在其保留期内仍可作为恢复来源使用(通过 pg_pitr.repo 指定)。
4 - 管理命令 备份管理命令手册:启用与移除备份,手动备份,查看与清理,Stanza 管理,日志排查,以及替代备份工具。
备份管理命令应以数据库超级用户(pg_dbsu ,默认 postgres)身份在数据库节点上执行。
您可以按习惯选择三种等价的入口:
pig pb :pig 命令行工具 的封装 —— 自动检测 stanza、自动切换 DBSU 身份、带安全检查,推荐使用 pb :登录 shell 的别名函数,自动填充 --stanza 后转发给 pgbackrestpgbackrest :原生命令,完整选项参阅 pgBackRest 命令参考 命令一览 pig 命令 别名 对应 pgbackrest 命令 说明 pig pb infoiinfo查看备份与归档状态 pig pb listls— 列出仓库中的 stanza 与备份 pig pb backup [full/diff/incr]bbackup执行备份(自动检查主库角色) pig pb restorerrestore恢复(显示计划并确认,详见 恢复操作 ) pig pb expireeexpire按保留策略清理过期备份(--plan 预览) pig pb createcstanza-create创建 stanza pig pb upgradeustanza-upgrade升级 stanza(版本升级或克隆善后) pig pb deletedstanza-delete删除 stanza 及其全部备份 pig pb checkckcheck校验备份配置与归档链路 pig pb startupstart恢复 pgbackrest 操作 pig pb stopdwstop暂停 pgbackrest 操作 pig pb log [list/show/tail]l— 查看 pgbackrest 日志
启用备份 如果集群创建时 pgbackrest_enabled 为 true(默认),备份已自动启用。
若创建时禁用了备份,或修改了仓库配置,可用 pg_backup 子任务补充配置:
./pgsql.yml -t pg_backup -l pg-meta # 配置 pgbackrest,创建 stanza
集群初始化后 Pigsty 会自动尝试执行一次初始全量备份(标记文件 /etc/pgbackrest/initial.done);该任务会忽略失败,标记也不能证明备份成功,应以 pb info 为准。
定时备份计划通过 pg_crontab 声明,详见 备份策略 。
移除备份 移除主实例(pg_role = primary)时,Pigsty 默认一并删除该集群的备份 stanza:
./pgsql-rm.yml # 移除集群(含备份)
./pgsql-rm.yml -e pg_rm_backup = false # 移除集群,但保留备份
./pgsql-rm.yml -t pg_backup # 仅删除备份,保留集群
使用 pg_rm_backup (设为 false)保留备份,使用 pg_backup 子任务只删备份。
如果备份仓库为对象版本配置了 对象锁定保留期 ,
删除可能只写入 Delete Marker,被锁定的历史版本会继续占用空间,直到保留期结束。
备份删除
删除备份可能导致永久性数据丢失,这是一个危险操作,请务必谨慎。
手动备份 crontab 之外,随时可以手动触发备份。pg-backup 脚本与 pig pb backup 都带主库角色检查,在从库上执行会直接退出,不会产生错误的备份:
pg-backup # 增量备份(仓库中无全量备份时自动升级为全量)
pg-backup full # 全量备份
pg-backup diff # 差异备份(相对最近一次全量)
pg-backup incr # 增量备份(相对最近一次任意备份)
pig pb backup full # 等价:pig 封装,自动检测 stanza 与 DBSU
备份期间会显著占用磁盘 I/O 与网络带宽(并行度已限制在 2~4 进程),建议安排在业务低峰执行。
查看备份 pb info 列出仓库中当前 stanza 的备份与 WAL 归档状态:
pb info # = pgbackrest --stanza=pg-meta info
pig pb info # 等价
pig pb list # 列出仓库中所有 stanza
输出解读的关键是 备份标签 :
20250715-013657F 为全量备份(F),..._20250715-013724D 为差异备份(D),..._20250715-013730I 为增量备份(I)——
下划线前的部分标识备份链所依附的全量备份。wal archive min/max 显示 WAL 归档范围,
它与最早的全量备份共同描述 恢复窗口 。
监控系统同样提供备份状态的持续观测:pgbackrest_exporter(端口 9854)导出的
指标 覆盖最近备份时间、类型、大小与错误状态,可直接用于告警。
清理过期备份 保留策略默认在每次备份后自动执行(expire-auto)。手动触发或预览清理计划:
pig pb expire --plan # 预览将被清理的备份(dry-run,不实际删除)
pig pb expire # 按保留策略执行清理
Stanza 管理 Stanza 记录集群的备份身份(system-id 与主版本),
以下场景需要手动管理:
pig pb create # 创建 stanza:新仓库初始化(Pigsty 集群初始化时自动执行)
pig pb upgrade # 升级 stanza:PostgreSQL 大版本升级后,或克隆恢复出新集群后
pig pb delete # 删除 stanza:连同其所有备份与归档一并删除,危险操作!
最常见的手动场景是 克隆集群的善后 :
从其他集群的备份恢复出新集群后,stanza 中记录的 system-id 与新集群不符,
必须执行 stanza-upgrade 之后,新集群的备份才能写入仓库。
检查与启停 pig pb check # 端到端校验:配置、归档推送、仓库可达性
pig pb stop # 暂停 pgbackrest 操作(维护窗口,阻止新备份/归档启动)
pig pb start # 恢复 pgbackrest 操作
check 命令会实际推送一个 WAL 段并确认其到达仓库,是排查"归档不工作"问题的第一步。
查看日志 pig pb log # 列出日志文件
pig pb log tail # 跟踪最新日志
ls /pg/log/pgbackrest/ # 日志目录:备份、归档、恢复各有独立日志文件
使用 pgsql-pitr.yml 时,PostgreSQL 的恢复日志位于 /pg/tmp/recovery.log。
替代备份工具 pg-basebackup Pigsty 另备有不依赖 pgbackrest 的独立备份脚本 /pg/bin/pg-basebackup,
它使用原生 pg_basebackup 生成单文件物理备份(lz4 压缩 tarball),默认写入 /pg/backup。
适合在不便使用备份仓库时快速留存一份物理副本:
pg-basebackup # 生成 /pg/backup/backup_<tag>_<date>.tar.lz4
pg-basebackup --dst /tmp --file backup.tar.lz4 # 指定输出位置与文件名
mkdir -p /tmp/data # 解压提取
cat /pg/backup/backup_pg-meta_20250713.tar.lz4 | unlz4 -d -c | tar -xC /tmp/data
加密选项为遗留实现
pg-basebackup -e 使用 OpenSSL RC4 加密 —— 这是一个已被淘汰的弱加密算法,仅作混淆用途,
不应作为机密性保障。需要加密备份时,请使用 pgbackrest 仓库的 AES-256 加密(cipher_type: aes-256-cbc)。
逻辑备份 pg_dump 生成的逻辑备份 不能 用于 PITR,但它是跨大版本迁移、导出部分数据、长期归档快照的正确工具。
物理备份与逻辑备份互为补充,严肃的生产环境通常两者兼备。这是 PostgreSQL 自带的工具,请参阅 官方文档
5 - 恢复操作 执行时间点恢复:pgsql-pitr.yml 剧本、pig pitr 命令与 pig pb restore 原语,恢复目标、分步执行与完整参数参考。
Pigsty 提供三个层次的恢复入口,共用 同一套参数语义 ,按场景选用:
手把手的沙箱演练教程请参阅 手工恢复 ;
用恢复克隆出新集群(不影响生产的推荐姿势)请参阅 克隆数据库集群 。
快速上手 要将 pg-meta 集群回滚到之前的时间点,声明 pg_pitr 参数并运行剧本:
pg-meta :
hosts : { 10.10.10.10 : { pg_seq : 1, pg_role : primary } }
vars :
pg_cluster : pg-meta
pg_pitr : { time : '2025-07-13 10:00:00+00', action : promote } # 一步执行:到达目标后显式提升
./pgsql-pitr.yml -l pg-meta
参数也可以通过命令行临时传入,两种方式等价:
./pgsql-pitr.yml -l pg-meta -e '{"pg_pitr": { "time": "2025-07-13 10:00:00+00", "action": "promote" }}'
命令行传参请使用合法 JSON
-e 传入的参数必须是合法 JSON:键与字符串值都要加双引号,例如 {"pg_pitr": {"time": "...", "archive": true}}。
布尔值不加引号,字符串必须加 —— 引号缺失会导致参数解析失败或静默取错值。
剧本会依次执行:暂停 Patroni 高可用 → 停止集群进程 → 执行 pgbackrest 增量还原 → 启动 PostgreSQL 并等待进入一致恢复状态 →
用 pg_controldata 打印控制信息 → 清理 etcd 元数据 → 重新拉起集群与高可用。
执行过程的第一步会打印完整的恢复计划(源集群、目标、还原命令),但不会暂停等待确认;上面的一步式示例因此显式声明了 action: promote。
如果需要在目标点检查数据,请使用下文的 分步执行 ,并显式选择 action: pause。
恢复目标 pg_pitr 支持 六类恢复目标 ,其中四类目标值互斥,只能指定一个:
恢复目标类型
default/latest
time
lsn
xid
name
immediate pg_pitr : { } # 恢复到最新状态(WAL 归档流末尾) pg_pitr : { time : "2025-07-13 10:00:00+00" }pg_pitr : { lsn : "0/4001C80" }pg_pitr : { xid : "250000" }pg_pitr : { name : "some_restore_point" }pg_pitr : { type : "immediate" }未指定任何目标时,重放全部 WAL 归档恢复到最新状态(内部类型 default);
immediate 类型在到达第一个一致点后立即停止,用于最快恢复出可用实例(例如验证备份)。
按时间恢复 最常用的目标。时间应为合法的 PostgreSQL TIMESTAMP 格式,建议带时区:YYYY-MM-DD HH:MM:SS+TZ:
./pgsql-pitr.yml -l pg-meta -e '{"pg_pitr": { "time": "2025-07-13 10:00:00+00", "action": "promote" }}'
按名称恢复 在高危变更前用 pg_create_restore_point 打点,恢复时便有了无歧义的目标:
SELECT pg_create_restore_point ( 'before_migration' );
./pgsql-pitr.yml -l pg-meta -e '{"pg_pitr": { "name": "before_migration", "action": "promote" }}'
按事务 ID 恢复 如果误删数据的事务号已知(从监控仪表盘或 CSVLOG 的 TXID 字段获取),
配合 exclusive 精确停在该事务 之前 ,一条数据都不多丢:
./pgsql-pitr.yml -l pg-meta -e '{"pg_pitr": { "xid": "250000", "exclusive": true, "action": "promote" }}'
按 LSN 恢复 LSN (日志序列号)标识 WAL 流中的精确位置,
可从 Pigsty 仪表盘的 PG LSN 面板获取;需要时可以用 timeline 指定目标时间线(默认 latest):
./pgsql-pitr.yml -l pg-meta -e '{"pg_pitr": { "lsn": "0/4001C80", "timeline": "1", "action": "promote" }}'
包含与排除
恢复目标默认是"包含"(inclusive)的:目标点上的事务会被重放。
exclusive: true 排除目标点本身 —— 例如 xid: 250000, exclusive: true 时,最后被重放的是 249999 号之前已提交的事务。
仅适用于 time、xid、lsn 目标,对应 PostgreSQL 的 recovery_target_inclusive 。
恢复来源 默认从本集群自己的备份恢复,三个字段可以改变恢复来源:
cluster:源 stanza —— 使用共享仓库中 其他集群 的备份恢复(克隆集群 的基础)repo:临时指定备份仓库定义(格式同 pgbackrest_repo 的仓库条目),例如从旧仓库或异地仓库恢复set:从指定的 备份标签 开始还原(默认自动选择目标点前最近的备份集,用 pb info 查看可用标签)./pgsql-pitr.yml -l pg-meta2 -e '{"pg_pitr": { "cluster": "pg-meta", "archive": false, "action": "promote" }}' # 用 pg-meta 的备份恢复 pg-meta2
./pgsql-pitr.yml -l pg-meta2 -e '{"pg_pitr": { "cluster": "pg-meta", "time": "2025-07-14 08:00:00+00", "archive": false, "action": "promote" }}' # 并指定时间点
分步执行 一步到位固然方便,但在生产事故中,您可能希望亲手控制每个阶段。剧本的任务树支持用 tags 三步走:
./pgsql-pitr.yml -l pg-meta -t down # 第一步:暂停 HA,停止 patroni 与 postgres
./pgsql-pitr.yml -l pg-meta -t pitr # 第二步:执行还原与重放,打印恢复控制信息
./pgsql-pitr.yml -l pg-meta -t up # 第三步:清理 etcd,拉起集群,恢复 HA
# down : # 停止高可用并关闭 patroni 和 postgres
# - pause : # 暂停 patroni 自动故障切换
# - stop : # 停止 patroni 和 postgres 服务
# - stop_patroni : # 停止 patroni 服务
# - stop_postgres : # 停止 postgres 服务
# pitr : # 执行 PITR 过程
# - config : # 生成 pgbackrest 配置和恢复脚本
# - restore : # 运行 pgbackrest 恢复命令
# - recovery : # 启动 postgres 并完成恢复
# - verify : # 验证恢复后的集群控制数据
# up: : # 启动 postgres / patroni 并恢复高可用
# - etcd : # 启动前清理 etcd 元数据
# - start : # 启动 patroni 和 postgres 服务
# - start_postgres : # 启动 postgres 服务
# - start_patroni : # 启动 patroni 服务
# - resume : # 恢复 patroni 自动故障切换
每步之间您可以检查状态:down 之后确认进程已停;pitr 阶段返回后,先查看 /pg/tmp/recovery.log,
并用 pg_is_in_recovery()、pg_is_wal_replay_paused()、pg_last_wal_replay_lsn() 与 pg_last_xact_replay_timestamp()
确认是否已经到达目标,再结合业务查询抽查数据。pg_controldata /pg/data 提供的是检查点与时间线摘要,不能单独证明时间、XID 或 LSN 目标已经命中。
使用 action: pause 时,确认无误后先提升实例,再执行 up;如果恢复目标选错了,可在 up 之前调整 pg_pitr 重跑 pitr 阶段。
pause / shutdown 需要配合这种分阶段流程才能形成明确的人工门;一步式执行应显式使用 action: promote。
SELECT pg_is_in_recovery (), pg_is_wal_replay_paused (),
pg_last_wal_replay_lsn (), pg_last_xact_replay_timestamp ();
pg_ctl -D /pg/data promote # action: pause 验证通过后执行
./pgsql-pitr.yml -l pg-meta -t up # 清理 etcd,拉起 Patroni,恢复 HA
重跑 pitr 阶段
backup: true 会把当前数据目录搬到 /pg/data-backup,而再次运行时会先删除已有的 /pg/data-backup。
因此剧本支持分阶段执行,但不能把带 backup: true 的恢复笼统视为幂等操作。
PITR 参数定义 pg_pitr 的完整字段如下。恢复目标、目标动作与原数据保留方式都建议显式声明:
pg_pitr : # 定义 PITR 恢复任务
cluster : pg-meta # 恢复来源集群(源 stanza),默认为本集群 pg_cluster
type : default # 目标类型:default | time | xid | name | lsn | immediate
time : "2025-07-13 10:00:00+00" # 恢复目标:时间点(与 xid / name / lsn 互斥)
name : "some_restore_point" # 恢复目标:命名恢复点(与 time / xid / lsn 互斥)
xid : "250000" # 恢复目标:事务 ID(与 time / name / lsn 互斥)
lsn : "0/4001C80" # 恢复目标:日志序列号(与 time / xid / name 互斥)
exclusive : false # 排除目标点本身,默认包含(仅 time / xid / lsn 有效)
timeline : latest # 目标时间线,可为整数,默认 latest
set : latest # 从哪个备份标签开始还原,默认自动选择
action : pause # 到达目标后动作:pause / promote / shutdown
# 指定恢复目标时未声明 action,实际默认 pause
archive : true # 保留原归档配置;探索性恢复设为 false(archive-mode=off)
backup : false # 恢复前将原数据目录搬到 /pg/data-backup;重跑会覆盖已有备份目录
db_exclude : [] # 排除的数据库(选择性恢复)
db_include : [] # 只恢复指定数据库(选择性恢复)
link_map : # 目录软链接映射(表空间 / WAL 分盘)
pg_wal : '/data/wal'
pg_xact : '/data/pg_xact'
process : 4 # 恢复并行进程数,默认为节点 CPU 核数
repo : {} # 临时指定恢复来源仓库(格式同 pgbackrest_repo 条目)
data : /pg/data # 恢复到的数据目录
port : 5432 # 恢复实例的监听端口
每个字段与 pgbackrest 选项的对应关系,见 参数映射表 。
单实例:pig pitr 在数据库节点上,pig pitr 无需 Ansible 环境即可执行单节点恢复编排:
预检(校验目标、stanza 与备份存在性)→ 停止 Patroni 与 PostgreSQL → 执行还原 → 按参数决定是否启动 PostgreSQL → 恢复后指引。
pig pitr -t "2025-07-13 10:00:00+00" # 恢复到时间点
pig pitr --xid 250000 -X # 恢复到事务 250000 之前(-X = --exclusive)
pig pitr --name before_migration # 恢复到命名还原点
pig pitr -d # 恢复到 WAL 归档末尾(--default)
pig pitr -I --no-restart # 只还原并准备 immediate 恢复,PostgreSQL 保持停止
pig pitr -t "..." --plan # 只显示执行计划,不实际执行
常用选项:-b/--set 指定备份集,-T/--target-timeline 指定时间线,--target-action 指定到达目标后的动作,
-D/--data 恢复到其他数据目录(此时必须配合 --no-restart)。
默认只用安全的 fast 模式停库,失败即中止 —— 除非显式给出 --force-stop,才允许升级为强制停库。
对于 Patroni 托管的数据目录,命令恢复后会让 Patroni 保持停止;验证数据后再执行 pig pt start。
pig pitr 不清理 etcd、不重建副本,也不会自动把实例重新加入 HA 集群。
完整选项参阅 pig pitr 命令手册 。
原语:pig pb restore 对于 不由 Patroni 托管 的实例(或已明确停管的场景),可以使用最底层的恢复原语 ——
它是 pgbackrest restore 的直接封装,自动处理 stanza、DBSU 与时间格式,
执行前显示恢复计划并要求确认:
pig pb restore --time "2025-07-13 10:00" # 时间可省略时区与秒,自动按本地时区规范化
pig pb restore --set 20250715-013657F # 从指定备份集恢复
pig pb restore -d # 恢复到归档末尾
两道内置的安全边界值得了解:
Patroni 托管实例会被硬拒绝 :若 Patroni 服务活跃且目标是其托管的数据目录,pig pb restore 直接报错退出 ——
因为 Patroni 会立刻把恢复到一半的实例重新拉起。托管实例请使用 pig pitr 或 pgsql-pitr.yml。PostgreSQL 必须已停止 :实例仍在运行时拒绝执行。-- 之后可透传原生 pgbackrest 选项(如 --tablespace-map、--link-all),
但恢复目标、stanza、仓库等关键选项已被封装接管,不允许透传覆盖。详见 pig pb 命令手册 。
恢复后处理 恢复完成后,剧本会打印控制信息并重建高可用,但仍有三件事需要确认:
核对数据 :按 分步执行 中的方法检查恢复目标与业务数据。
重建备份 :如果是从其他集群克隆恢复,需要执行 stanza 善后 ;
无论何种恢复,都建议尽快执行一次全量备份,在新时间线上重建恢复起点:
恢复归档 :探索性恢复若设置了 archive: false,归档已被关闭,验证完成后必须恢复
(archive_mode 是 postmaster 参数,需要重启生效):
psql -c 'ALTER SYSTEM RESET archive_mode;'
pg restart pg-meta # 重启集群使归档配置生效
pg-backup full # 执行新的全量备份
6 - 克隆数据库集群 用 PITR 把一个集群的历史状态恢复到另一个集群:找回误删数据、执行恢复演练,以及必不可少的 Stanza 善后。
克隆是恢复能力最有价值的用法:不动生产集群 ,把它的历史状态恢复到另一套集群上。
误删数据后从克隆库中导回、定期演练验证备份可用性、审计取证查看历史状态、把测试环境重置为生产某刻的快照 ——
这些场景的操作方式完全相同,本页给出完整流程。
目标集群需要能访问源集群的备份仓库、允许被覆盖,并使用兼容的 PostgreSQL 主版本。使用集中式仓库(MinIO / S3 )时,
仓库中以 stanza 隔离的各集群备份,对持有相应凭据的目标集群可见。
克隆现有集群 假设四节点沙箱中有 pg-meta 与 pg-test 两套集群,共享 MinIO 备份仓库。
要把 pg-test 重置为 pg-meta 的 最新状态 ,只需在 pg_pitr
中把恢复来源指向 pg-meta 的 stanza:
./pgsql-pitr.yml -l pg-test -e '{"pg_pitr": { "cluster": "pg-meta", "archive": false, "action": "promote" }}'
配合恢复目标,可以克隆到恢复窗口内的 任意时间点 —— 例如把 pg-test 重置为 pg-meta
在 2025 年 12 月 26 日 15:30 的状态:
./pgsql-pitr.yml -l pg-test -e '{"pg_pitr": { "cluster": "pg-meta", "time": "2025-12-26 15:30:00+08", "archive": false, "action": "promote" }}'
跨集群克隆显式设置 archive: false,在独立恢复阶段关闭归档;Patroni 接管后按下面的步骤处理目标 stanza 与归档。
目标集群也可以是全新创建的空集群:先用标准流程 创建集群 (如 pg-meta2),
再对它执行跨集群 PITR,即完成了"从备份仓库引导新集群"。
pgBackRest 的还原是增量的(delta):只重写与备份不一致的文件。
因此对反复执行的演练、或已通过 备份集群 (Standby Cluster)
物理复制拉齐过数据的目标集群,克隆速度会显著快于首次全量还原。
误删数据的典型找回流程到这里只剩最后一步:在克隆集群中验证数据无误后,
用 pg_dump 导出受影响的表/库,导回生产集群。全库原地回滚是最后手段,而不是第一反应。
克隆善后 克隆出的新集群带着 源集群的数据 ,但备份仓库中它自己的 stanza 仍记录着 原来的身份 (system-id)。
pgBackRest 写入备份前会核对身份,不一致即拒绝 —— 这个保护机制防止新集群的备份污染源集群的备份历史。
因此,确认克隆结果符合预期后,必须执行三步善后,新集群的备份链路才能恢复正常:
pb stanza-upgrade # 1. 升级 stanza,接纳新集群的 system-id(仅跨集群克隆需要)
psql -c 'ALTER SYSTEM RESET archive_mode;' # 2. 恢复归档(本文跨集群示例显式设置了 archive: false)
pg restart pg-test # archive_mode 为 postmaster 参数,重启生效
pg-backup full # 3. 全量备份,让新集群从此刻起拥有自己的备份历史
跳过善后的后果是可预期的:下一次例行备份会因身份核对失败而报错,
在此期间新集群 没有备份保护 (如果关闭了归档,也不会产生新的 WAL 归档):
postgres@pg-test-1:~$ pb backup
INFO: backup command begin 2.57.0: --annotation= pg_cluster = pg-test ... --stanza= pg-test --start-fast
ERROR: [ 051] : PostgreSQL version 18, system-id 7588470953413201282 do not match stanza version 18, system-id 7588470974940466058
HINT: is this the correct stanza?
INFO: backup command end: aborted with exception [ 051]
重建备份身份 stanza-upgrade 让新集群沿用原 stanza 继续写备份。如果您希望新集群拥有 全新的备份历史
(例如克隆出的集群将长期独立演化),也可以选择彻底重建其备份配置 —— 声明式方式:
./pgsql-rm.yml -t pg_backup -l pg-test -e pg_rm_backup = true # 删除 pg-test 的 stanza 与旧备份
./pgsql.yml -t pg_backup -l pg-test # 重新配置 pgbackrest,创建全新 stanza
pg-backup full # 建立第一个恢复点
或者用 pgbackrest 原语 手动完成同样的事情:
pb stop --force # 暂停 pgbackrest 操作
pb stanza-delete --force # 删除 stanza 及其备份(危险操作,确认无误再执行)
pb start # 恢复 pgbackrest 操作
pb stanza-create # 以当前集群身份重建 stanza
pg-backup full # 建立第一个恢复点
在线副本:备份集群 克隆得到的是 静态的时间点快照 。如果需要的是持续跟随源集群的 在线副本 ,
应使用 备份集群 (Standby Cluster,基于流复制);
需要"一直落后一小时"的快速反悔窗口,则使用 延迟集群 。
三者互为补充:备份集群提供实时副本,延迟集群提供固定延迟的反悔窗口,
PITR 克隆提供恢复窗口内的历史快照 —— 且不需要提前准备在线副本。
恢复演练 克隆是 不触碰生产集群的恢复演练 :目标集群会被覆盖,但它能端到端验证备份系统的每个环节。
建议将以下演练纳入例行运维(每季度,或每次重大变更后):
选定演练目标:生产集群恢复窗口内的某个时间点; 向演练集群执行跨集群 PITR,记录耗时 —— 这就是实测的 PITR RTO; 验证数据完整性:行数抽查、关键业务表校验、应用连通测试; 执行 克隆善后 ,确认演练集群自身备份恢复正常(验证善后流程本身也是演练的一部分); 记录结果:恢复耗时、发现的问题、文档与实际操作的出入。 沙箱环境中使用 pgbackrest 原语手工执行恢复的完整教程,参阅 手工恢复 ;
在同一台机器上用 XFS 快照快速 Fork 实例的进阶技巧,参阅 Fork 实例 。