SQL Academy · 课时

时间点恢复

使用 WAL 恢复到任意时刻

第 2 / 4 课13 个步骤

时间点恢复 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

什么是时间点恢复

时间点恢复(PITR)可以将数据库恢复到过去的任何特定时刻,而不仅仅是最近一次备份快照的时间。

这是因为 PostgreSQL 会持续将每项更改写入称为预写式日志(WAL)的数据流。通过在基础备份之上重放 WAL 记录,您可以准确恢复到所需的位置。

预写式日志(WAL)

每条 INSERT、UPDATE、DELETE 和 DDL 语句都会先写入 WAL,然后才修改实际数据文件。这可以确保即使服务器在写入过程中崩溃,数据仍具有持久性。

对于 PITR,已归档的 WAL 段就像时间机器的磁带。基础备份是起点,而 WAL 会补齐之后发生的一切。

-- Check current WAL write location
SELECT pg_current_wal_lsn() AS current_lsn,
       pg_walfile_name(pg_current_wal_lsn()) AS current_wal_file;

启用 WAL 归档

在能够执行 PITR 之前,必须在 postgresql.conf 中启用 WAL 归档。关键参数包括 wal_level、archive_mode 和 archive_command。

归档命令会将每个已完成的 WAL 段复制到安全位置,例如本地目录、NFS 挂载点或云存储桶。

-- View current WAL and archive settings
SELECT name, setting, unit
FROM   pg_settings
WHERE  name IN (
  'wal_level',
  'archive_mode',
  'archive_command',
  'archive_status'
)
ORDER  BY name;

创建基础备份

基础备份是在服务器运行期间创建的整个数据目录的一致副本。PostgreSQL 提供了 pg_basebackup 工具和用于协调此过程的底层 SQL 函数。

将该备份与从备份开始时间起记录的已归档 WAL 段结合起来,就构成执行 PITR 所需的全部内容。

-- Check the latest base backup information
SELECT backup_start,
       backup_end,
       pg_size_pretty(backup_total) AS total_size
FROM   pg_stat_basebackup;

标记恢复目标时间

灾难发生时,第一步是确定您希望恢复到的准确时间戳。常见做法是找到有害事件发生之前的时间戳,例如意外执行大规模 DELETE 之前的时间。

事务日志表或应用日志通常会保存这个时间戳。当 track_commit_timestamp 启用时,WAL 本身会记录提交时间戳。

-- Find the commit timestamp of recent transactions (requires track_commit_timestamp=on)
SELECT xid,
       pg_xact_commit_timestamp(xid::xid) AS committed_at
FROM   pg_stat_activity
WHERE  state = 'idle'
LIMIT  10;

recovery.conf / 恢复参数

恢复行为由放置在 postgresql.conf(PostgreSQL 12+)中的参数控制;在更早的版本中,则由旧版 recovery.conf 文件控制。最重要的参数包括:

  • restore_command — 如何获取已归档的 WAL 段
  • recovery_target_time — 停止恢复的准确时间戳
  • recovery_target_action — 到达目标时要执行的操作(promote、pause、shutdown)
-- Inspect recovery settings that are currently active
SELECT name, setting
FROM   pg_settings
WHERE  name IN (
  'restore_command',
  'recovery_target_time',
  'recovery_target_action',
  'recovery_target_inclusive'
)
ORDER  BY name;

其他恢复目标类型

时间并不是唯一可以确定恢复目标的方式。PostgreSQL 支持四种目标类型:

  • recovery_target_time — 时间戳字符串
  • recovery_target_xid — 特定的事务 ID
  • recovery_target_lsn — WAL 日志序列号
  • recovery_target_name — 使用 pg_create_restore_point() 创建的命名恢复点
-- Create a named restore point before a risky migration
SELECT pg_create_restore_point('before_migration_2024_07_01') AS restore_lsn;

模拟灾难

为了在测试环境中练习 PITR,请先记下当前时间,然后有意损坏或删除数据。这样您就可以验证恢复是否回到了正确的时刻,以及已删除的行是否恢复。

-- Record the 'safe' timestamp, then simulate an accident
SELECT now() AS safe_point;

-- (In a test DB only!) accidentally delete important rows
DELETE FROM orders WHERE created_at < '2024-01-01';

-- Confirm the damage
SELECT COUNT(*) AS remaining_orders FROM orders;

执行恢复

恢复包括三个步骤:

  1. 停止正在运行的 PostgreSQL 实例。
  2. 将基础备份恢复到数据目录。
  3. 配置恢复参数并以恢复模式启动 PostgreSQL — 它会重放 WAL,直到达到目标时间,然后提升为正常的读写服务器。

服务器日志会显示每个 WAL 文件的应用过程,因此可以轻松跟踪进度。

-- After recovery completes, confirm the cluster is no longer in recovery
SELECT pg_is_in_recovery() AS in_recovery,
       pg_last_xact_replay_timestamp() AS last_replayed_txn;

验证恢复

服务器完成提升后,请验证数据是否处于预期状态。检查行数、最新行的时间戳以及任何业务关键值。

建议在允许应用流量恢复之前运行这些验证查询,这样如果需要,您可以继续恢复或调整目标时间。

-- Verify row counts and the latest transaction timestamp after recovery
SELECT 'orders'       AS tbl, COUNT(*) AS rows FROM orders
UNION ALL
SELECT 'order_items'  AS tbl, COUNT(*) AS rows FROM order_items
UNION ALL
SELECT 'customers'    AS tbl, COUNT(*) AS rows FROM customers
ORDER  BY tbl;

PITR 最佳实践

可靠的 PITR 设置不仅需要开启归档。关键实践包括:

  • 定期测试恢复 — 未经测试的备份就不算备份。
  • 监控 WAL 归档延迟 — 已归档 WAL 中的缺口会使完整恢复无法进行。
  • 保留足够的 WAL 历史记录 — 保留的片段至少要追溯到最早的有效基础备份。
  • 使用独立的存储位置 — 如果主磁盘发生故障,同一磁盘上的已归档 WAL 也会丢失。
-- Check for any WAL archiving failures
SELECT archived_count,
       failed_count,
       last_archived_wal,
       last_archived_time,
       last_failed_wal,
       last_failed_time
FROM   pg_stat_archiver;

快速检查

测试您对时间点恢复的理解。

回顾:时间点恢复

在本课中,您学习了 PostgreSQL 的预写日志如何实现恢复到过去的任意时刻:

  • WAL 归档会捕获基础备份之后的每项更改。
  • 恢复目标可以是时间戳、事务 ID、LSN 或命名恢复点。
  • 恢复过程会恢复基础备份,重放已归档的 WAL,并在达到目标后完成提升。
  • 验证会在重新开放流量前确认数据完整性。
  • 最佳实践包括定期恢复测试、归档监控和异地 WAL 存储。

PITR 是应对人为错误和数据损坏的安全网——掌握它,您就掌握了灾难恢复。

免费开始

用 AI 导师学习 SQL — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
46
课程
183

常见问题解答

「时间点恢复」课时是免费的吗?

是的 — 「时间点恢复」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「时间点恢复」这节课中我会学到什么?

使用 WAL 恢复到任意时刻 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「时间点恢复」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 逻辑备份与物理备份
  2. 时间点恢复
  3. 测试恢复结果
  4. 灾难恢复规划
← 返回 SQL Academy