恢复机制

恢复命令、恢复场景与操作步骤详解。

本文介绍如何使用 Pigsty 的备份进行时间点恢复,包括常见恢复场景和操作步骤。


恢复工具

Pigsty 提供了封装好的恢复脚本:

/pg/bin/pg-pitr    # PITR 恢复脚本

也可以直接使用 pgBackRest 命令:

pgbackrest --stanza=<cluster> restore [options]

恢复场景

场景一:恢复到指定时间点

情况:用户在 10:30 误删了一张表,需要恢复到 10:29 的状态。

# 停止 PostgreSQL
sudo systemctl stop patroni

# 恢复到指定时间点
pg-pitr --time="2024-01-15 10:29:00"

# 启动 PostgreSQL
sudo systemctl start patroni

场景二:恢复到最新状态

情况:主库磁盘损坏,需要从备份恢复全部数据。

# 停止 PostgreSQL
sudo systemctl stop patroni

# 恢复到最新可用状态
pg-pitr --type=immediate

# 启动 PostgreSQL
sudo systemctl start patroni

场景三:恢复到新实例

情况:不影响现有服务,将备份恢复到一个新的实例进行验证。

# 在新节点上执行恢复
pgbackrest --stanza=pg-meta restore \
  --target-time="2024-01-15 10:29:00" \
  --pg1-path=/pg/data \
  --target-action=promote

# 启动新实例
pg_ctl start -D /pg/data

恢复参数

时间目标

# 恢复到指定时间点
pg-pitr --time="2024-01-15 10:29:00"

# 使用 ISO 8601 格式
pg-pitr --time="2024-01-15T10:29:00+08:00"

事务 ID 目标

# 恢复到指定事务 ID
pg-pitr --xid=12345678

LSN 目标

# 恢复到指定 LSN
pg-pitr --lsn="0/12345678"

命名恢复点

如果提前创建了恢复点:

-- 在数据库中创建恢复点
SELECT pg_create_restore_point('before_migration');

可以恢复到该点:

pg-pitr --name="before_migration"

恢复流程

标准恢复流程

1. 评估情况
   ↓
2. 确定恢复目标(时间/事务/LSN)
   ↓
3. 停止 PostgreSQL 服务
   ↓
4. 备份当前数据目录(可选)
   ↓
5. 执行恢复命令
   ↓
6. 验证恢复结果
   ↓
7. 启动 PostgreSQL 服务
   ↓
8. 重新配置复制关系(如需要)

详细步骤

第一步:停止服务

# 停止 Patroni(会自动停止 PostgreSQL)
sudo systemctl stop patroni

# 确认已停止
pg_isready -h /tmp

第二步:备份当前数据(可选)

# 如果需要保留当前状态
mv /pg/data /pg/data.bak.$(date +%Y%m%d%H%M%S)

第三步:执行恢复

# 使用 Pigsty 封装脚本
pg-pitr --time="2024-01-15 10:29:00"

# 或使用 pgBackRest 原生命令
pgbackrest --stanza=pg-meta restore \
  --target-time="2024-01-15 10:29:00" \
  --target-action=promote \
  --delta

第四步:启动服务

# 启动 Patroni
sudo systemctl start patroni

# 检查状态
patronictl -c /pg/bin/patroni.yml list

第五步:验证恢复

# 检查数据是否正确恢复
psql -c "SELECT * FROM recovered_table LIMIT 10;"

恢复选项

–delta

增量恢复,只替换有变化的文件:

pg-pitr --time="..." --delta

优势:恢复速度更快,特别是数据变化不大时。

–target-action

恢复完成后的动作:

选项 说明
promote(默认) 提升为可写状态
pause 暂停在恢复完成点
shutdown 关闭数据库

–type

恢复类型:

选项 说明
time 恢复到指定时间
xid 恢复到指定事务 ID
lsn 恢复到指定 LSN
name 恢复到命名恢复点
immediate 恢复到最新可用状态

注意事项

时间线变更

PITR 恢复会创建新的时间线,恢复后:

  • 时间线 ID 增加
  • 无法直接与原时间线的从库同步
  • 需要重新初始化从库

从库处理

恢复主库后,从库需要:

# 方式一:重新初始化从库
patronictl -c /pg/bin/patroni.yml reinit <cluster> <replica>

# 方式二:从备份重建从库
pg-pitr --type=immediate --delta  # 在从库节点执行

验证备份

定期验证备份可恢复性:

# 检查备份完整性
pgbackrest --stanza=pg-meta check

# 验证备份信息
pgbackrest --stanza=pg-meta info

常见问题

Q:恢复需要多长时间?

取决于:

  • 数据库大小
  • 备份仓库位置(本地/远程)
  • 需要重放的 WAL 数量
  • 磁盘/网络 IO 性能

经验值:100GB 数据库,本地备份,恢复约 15-30 分钟。

Q:可以恢复到任意时间点吗?

只能恢复到 WAL 归档覆盖的时间范围内。如果 WAL 已被清理,则无法恢复到那之前的时间点。

Q:恢复会影响现有服务吗?

在原实例上恢复会导致服务中断。如需不中断服务,可以恢复到新实例。