恢复操作
Pigsty 提供三个层次的恢复入口,共用 同一套参数语义,按场景选用:
| 入口 | 适用场景 | 特点 |
|---|---|---|
pgsql-pitr.yml 剧本 |
生产集群恢复 | 编排整个集群:HA 暂停、多节点、etcd 清理、恢复控制信息输出 |
pig pitr 命令 |
单节点集群 / 节点本机操作 | 无需管理节点,在数据库节点上直接编排执行 |
pig pb restore 原语 |
非 Patroni 托管的实例 | pgbackrest restore 的直接封装,最精细的控制 |
手把手的沙箱演练教程请参阅 手工恢复; 用恢复克隆出新集群(不影响生产的推荐姿势)请参阅 克隆数据库集群。
pgsql-pitr.yml 会暂停 HA、停止 Patroni/PostgreSQL、以 pgbackrest --force restore 覆盖目标数据目录,
随后删除目标集群的 etcd 前缀并重建 HA;它只打印计划,不会等待人工确认。
执行任何实质恢复前,必须先用 pig pg list <目标集群> 核对当前拓扑、用 pig pb info 核对近期备份与恢复窗口,
由操作者复述并确认精确的目标集群与恢复点。生产恢复仍应安排维护窗口并保留独立、已验证的备份。
快速上手
要将 pg-meta 集群回滚到之前的时间点,声明 pg_pitr 参数并运行剧本:
参数也可以通过命令行临时传入,两种方式等价:
-e 传入的参数必须是合法 JSON:键与字符串值都要加双引号,例如 {"pg_pitr": {"time": "...", "archive": true}}。
布尔值不加引号,字符串必须加 —— 引号缺失会导致参数解析失败或静默取错值。
剧本会依次执行:暂停 Patroni 高可用 → 停止集群进程 → 执行 pgbackrest 增量还原 → 启动 PostgreSQL 并等待进入一致恢复状态 →
用 pg_controldata 打印控制信息 → 清理 etcd 元数据 → 重新拉起集群与高可用。
执行过程的第一步会打印完整的恢复计划(源集群、目标、还原命令),但不会暂停等待确认;上面的一步式示例因此显式声明了 action: promote。
如果需要在目标点检查数据,请使用下文的 分步执行,并显式选择 action: pause。
恢复目标
pg_pitr 支持 六类恢复目标,其中四类目标值互斥,只能指定一个:
恢复目标类型
未指定任何目标时,重放全部 WAL 归档恢复到最新状态(内部类型 default);
immediate 类型在到达第一个一致点后立即停止,用于最快恢复出可用实例(例如验证备份)。
按时间恢复
最常用的目标。时间应为合法的 PostgreSQL TIMESTAMP 格式,建议带时区:YYYY-MM-DD HH:MM:SS+TZ:
按名称恢复
在高危变更前用 pg_create_restore_point 打点,恢复时便有了无歧义的目标:
按事务 ID 恢复
如果误删数据的事务号已知(从监控仪表盘或 CSVLOG 的 TXID 字段获取),
配合 exclusive 精确停在该事务 之前,一条数据都不多丢:
按 LSN 恢复
LSN(日志序列号)标识 WAL 流中的精确位置,
可从 Pigsty 仪表盘的 PG LSN 面板获取;需要时可以用 timeline 指定目标时间线(默认 latest):
恢复目标默认是"包含"(inclusive)的:目标点上的事务会被重放。
exclusive: true 排除目标点本身 —— 例如 xid: 250000, exclusive: true 时,最后被重放的是 249999 号之前已提交的事务。
仅适用于 time、xid、lsn 目标,对应 PostgreSQL 的 recovery_target_inclusive。
恢复来源
默认从本集群自己的备份恢复,三个字段可以改变恢复来源:
cluster:源 stanza —— 使用共享仓库中 其他集群 的备份恢复(克隆集群 的基础)repo:临时指定备份仓库定义(格式同pgbackrest_repo的仓库条目),例如从旧仓库或异地仓库恢复set:从指定的 备份标签 开始还原(默认自动选择目标点前最近的备份集,用pb info查看可用标签)
分步执行
一步到位固然方便,但在生产事故中,您可能希望亲手控制每个阶段。剧本的任务树支持用 tags 三步走:
每步之间您可以检查状态: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。
backup: true 会把当前数据目录搬到 /pg/data-backup,而再次运行时会先删除已有的 /pg/data-backup。
因此剧本支持分阶段执行,但不能把带 backup: true 的恢复笼统视为幂等操作。
PITR 参数定义
pg_pitr 的完整字段如下。恢复目标、目标动作与原数据保留方式都建议显式声明:
每个字段与 pgbackrest 选项的对应关系,见 参数映射表。
单实例:pig pitr
在数据库节点上,pig pitr 无需 Ansible 环境即可执行单节点恢复编排:
预检(校验目标、stanza 与备份存在性)→ 停止 Patroni 与 PostgreSQL → 执行还原 → 按参数决定是否启动 PostgreSQL → 恢复后指引。
常用选项:-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 与时间格式,
执行前显示恢复计划并要求确认:
两道内置的安全边界值得了解:
- 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 参数,需要重启生效)。先确认维护窗口、当前主库和复制状态,再由操作者明确批准重启: