时间点恢复
从备份恢复 PostgreSQL
您可以使用预配置的 pgbackrest 在 Pigsty 中执行时间点恢复(PITR)。
如果您对配置非常熟悉,可以使用全自动剧本, 否则,考虑逐步手动操作
快速开始
如果您想将 pg-meta
集群回滚到之前的时间点,添加 pg_pitr
:
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta2
pg_pitr: { time: '2025-07-13 10:00:00+00' } # 从最新备份恢复
然后运行 pgsql-pitr.yml
剧本,它将把 pg-meta
集群回滚到指定的时间点。
./pgsql-pitr.yml -l pg-meta
恢复 PITR
恢复的集群上的 archive_mode
将被禁用,以防止不必要的 WAL 写入。
如果恢复的数据库状态正常,您可以启用 archive_mode
并进行全量备份。
psql -c 'ALTER SYSTEM RESET archive_mode; SELECT pg_reload_conf();'
pg-backup full # 进行新的全量备份
恢复目标
您可以在 pg_pitr
中指定不同类型的恢复目标,但它们是互斥的:
time
:恢复到哪个时间点?name
:恢复到命名的恢复点(由pg_create_restore_point
创建)xid
:恢复到特定的事务 ID(TXID/XID)lsn
:恢复到特定的 LSN(日志序列号)点
如果指定了上述任何参数,恢复 type
将相应设置,
否则将设置为 latest
(WAL 归档流的末尾)。
特殊的 immediate
类型可用于指示 pgbackrest 通过在第一个一致点停止来最小化恢复时间。
目标类型
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" }
按时间
最常用的目标是时间点;您可以指定要恢复到的时间点:
./pgsql-pitr.yml -e '{"pg_pitr": { "time": "2025-07-13 10:00:00+00" }}'
时间应该是有效的 PostgreSQL TIMESTAMP
,建议使用 YYYY-MM-DD HH:MM:SS+TZ
。
按名称
您可以使用 pg_create_restore_point
创建命名的恢复点:
SELECT pg_create_restore_point('shit_incoming');
并在 PITR 中使用该命名恢复点:
./pgsql-pitr.yml -e '{"pg_pitr": { "name": "shit_incoming" }}'
按 XID
如果您有一个意外删除某些数据的事务,最好的恢复方法是将数据库恢复到该事务之前的状态。
./pgsql-pitr.yml -e '{"pg_pitr": { "xid": "250000", exclusive: true }}'
您可以从监控仪表板找到确切的事务 ID,或从 CSVLOG 的 TXID
中找到它。
包含 vs 排除
目标参数默认是"包含"的,这意味着恢复将包含目标点。
exclusive
标志将排除那个确切的目标,比如 xid 24999 将是最后一个被重放的事务
这仅适用于 time
、xid
、lsn
恢复目标,详情请查看 recovery_target_inclusive
。
按 LSN
PostgreSQL 使用 LSN(日志序列号)来标识 WAL 记录的位置。 您可以在任何地方找到它,比如 Pigsty 仪表板的 PG LSN 面板。
./pgsql-pitr.yml -e '{"pg_pitr": { "lsn": "0/4001C80", timeline: "1" }}'
要恢复到 WAL 流中的确切点,您还可以指定 timeline
参数(默认为 latest
)
恢复源
cluster
:恢复哪个集群?默认使用当前的pg_cluster
,您可以在同一个 pgbackrest 仓库中使用任何其他集群repo
:覆盖备份仓库,使用与pgbackrest_repo
相同的格式set
:默认使用latest
备份集,但您可以指定特定的 pgbackrest 备份标签
Pigsty 将从 pgbackrest 备份仓库恢复,如果您使用集中式备份仓库(如 MinIO/S3), 您可以指定另一个"stanza"(另一个集群的备份目录)来恢复。
pg-meta2:
hosts: { 10.10.10.11: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta2
pg_pitr: { cluster: pg-meta } # 从 pg-meta 集群备份恢复
上述配置将标记 PITR 过程使用 pg-meta
stanza。
您也可以通过 CLI 参数传递 pg_pitr
参数:
./pgsql-pitr.yml -l pg-meta2 -e '{"pg_pitr": { "cluster": "pg-meta" }}'
从另一个集群进行 pitr 时,您也可以使用这些目标:
./pgsql-pitr.yml -l pg-meta2 -e '{"pg_pitr": { "cluster": "pg-meta", "time": "2025-07-14 08:00:00+00" }}'
分步执行
这种方法是半自动的,您将参与 PITR 过程以做出关键决策。
例如,此配置将把 pg-meta
集群本身恢复到指定的时间点
pg-meta:
hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
vars:
pg_cluster: pg-meta2
pg_pitr: { time: '2025-07-13 10:00:00+00' } # 从最新备份恢复
让我们逐步执行:
./pgsql-pitr.yml -l pg-meta -t down # 暂停 patroni HA
./pgsql-pitr.yml -l pg-meta -t pitr # 运行 pitr 过程
./pgsql-pitr.yml -l pg-meta -t up # 生成 pgbackrest 配置和恢复脚本
# down : # 停止 ha 并关闭 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 并恢复 ha
# - etcd : # 在启动前清理 etcd 元数据
# - start : # 启动 patroni 和 postgres 服务
# - start_postgres : # 启动 postgres 服务
# - start_patroni : # 启动 patroni 服务
# - resume : # 恢复 patroni 自动故障转移
PITR 定义
pg_pitr
参数中有更多可用选项,以下是一些可用的参考项:
pg_pitr: # 定义 PITR 任务
cluster: "some_pg_cls_name" # 源集群名称
type: latest # 恢复目标类型:time、xid、name、lsn、immediate、latest
time: "2025-01-01 10:00:00+00" # 恢复目标:时间,与 xid、name、lsn 互斥
name: "some_restore_point" # 恢复目标:命名恢复点,与 time、xid、lsn 互斥
xid: "100000" # 恢复目标:事务 ID,与 time、name、lsn 互斥
lsn: "0/3000000" # 恢复目标:日志序列号,与 time、name、xid 互斥
timeline: latest # 目标时间线,可以是整数,默认为 latest
exclusive: false # 排除目标点,默认为 false?
action: pause # 恢复后操作:pause、promote、shutdown
archive: false # 保留归档设置?默认为 false
db_exclude: [ template0, template1 ]
db_include: []
link_map:
pg_wal: '/data/wal'
pg_xact: '/data/pg_xact'
process: 4 # 并行恢复进程
repo: {} # 要恢复的仓库
data: /pg/data # 恢复数据的位置
port: 5432 # 恢复实例的监听端口