当前位置: 代码网 > it编程>数据库>MsSqlserver > PostgreSQL .history 文件详解

PostgreSQL .history 文件详解

2026年04月30日 MsSqlserver 我要评论
一、什么是 .history 文件?  .history 文件是 postgresql 的时间线历史文件(timeline history file),位于 $pgdata/pg_

一、什么是 .history 文件?

  .history 文件是 postgresql 的时间线历史文件(timeline history file),位于 $pgdata/pg_wal/ 目录下(postgresql 10 之前为 pg_xlog),文件命名格式为 000000xx.history(例如 00000009.history),其中 xx 为八位十六进制表示的时间线 id(timeline id)。在 postgresql 运维中,.history 文件是一个虽不起眼却至关重要的元数据文件。它仅在时间线发生分叉时才产生,但一旦被误删,就会导致 pg_basebackup 备份失败、物理备库无法重建等一系列连锁反应。

它是一个纯文本文件,每一行记录一次时间线切换事件,格式如下:

<parenttli> <switchpoint> <reason>
  • parenttli:父时间线 id;
  • switchpoint:产生分叉的 wal 位置(lsn);
  • reason:产生时间线分叉的原因说明(如 no recovery target specified)。

一个典型的 00000002.history 文件内容如下:

1    0/a000198    before 2018-7-9 12:05:00.861324+00

每一行都代表一次时间线分裂事件,记录了当前时间线是从哪条时间线、在哪个 wal 位置分叉出来的,以及分叉的原因。

内容中的“原因”条目

reason 字段的具体取值取决于时间线切换的触发方式:

  • pitr 完成时reason 通常显示 no recovery target specified 或恢复目标相关的描述,标明恢复的边界条件。
  • 备库提升(promote)时reason 可能涉及提升操作的相关上下文信息。
  • pg_rewind 操作:reason 会体现 pg_rewind 导致的 timeline 调整。

需要注意的是,不同 postgresql 版本中的 reason 字段格式可能存在细微差异,但每条记录都至少包含父时间线 id 和分叉点 lsn 这两个核心要素。

二、时间线(timeline)

  理解 .history 文件,必须先了解 postgresql 的时间线概念。这一概念从 postgresql 8.0 开始引入,旨在解决 pitr(point-in-time recovery,时间点恢复)中的 wal 覆盖问题。考虑如下场景:管理员将数据库恢复到业务受损前的某个时间点后继续运行。若仍沿用原时间线,新生成的 wal 文件将与旧 wal 文件同名,导致原有的 wal 记录被覆盖,无法再次恢复到其他时间点。为解决这一问题,postgresql 引入了时间线机制。每当数据库集簇通过恢复启动后继续运行时,postgresql 都会切换到一条新的时间线——新生成的时间线 id 在旧的时间线 id 基础上加 1,并且生成一个 .history 文件记录本次分叉的完整信息。wal 文件名本身包含时间线 id(前 8 位十六进制数),这一设计保证了新的时间线不会覆盖旧时间线产生的 wal 文件。因此,时间线是进行精确 pitr、搭建多级备库等操作的核心基石。

2.1 关于时间线切换的触发时机

一个常见的理解偏差是认为“每次备库提升为主库都会产生一条新的时间线”。这种说法并非完全错误,但需要明确两点:

  • 单纯的主备复制过程中不会产生时间线切换。备库仅仅回放主库发送的 wal 记录,始终运行在与主库相同的时间线上。
  • 时间线切换发生在以下两种情况
    • 对备库执行 pg_ctl promote 命令,将其提升为独立的可写主库;
    • 基于 pitr(时间点恢复)将数据库恢复到过去某一时刻,然后让数据库以读写模式继续运行。

无论是在 postgresql 12 之前的 recovery.conf 中设置 promoterecovery_target_timeline,还是在新版本的 postgresql.conf 中配置相关参数,其本质都是恢复过程结束后数据库重新启动这一动作触发了时间线的新建。

2.2 关于版本差异的特别说明

postgresql 12 及以后版本中,recovery.conf 文件的功能已被整合到主配置文件 postgresql.confpostgresql.auto.conf 中,但时间线切换的触发机制并未改变。

三、.history 文件的核心作用

.history 文件在以下三个核心场景中发挥作用:

  • pitr(时间点恢复):恢复时,postgresql 需要读取 .history 文件,结合 recovery_target_timeline 参数来确定目标时间线的完整分支路径。
  • 流复制协议与备库构建:当使用 pg_basebackup 或流复制启动时,postgresql 需要通过复制协议读取主库的 .history 文件,以便备库理解主库完整的时间线谱系。
  • pg_rewindpg_rewind 工具依赖时间线历史文件来判断源集簇和目标集簇的分叉点,从而将旧主库同步至新时间线。

四、.history 文件缺失的影响

  .history 文件缺失对数据库日常运行无直接影响。 数据库常规事务处理、checkpoint、wal 切换等操作依赖 wal 段文件,不依赖 .history 文件。因此,删除了 .history 文件,数据库可以继续正常运行——这也是该文件易被忽视的重要原因。

受影响的操作

一旦 .history 文件被误删,以下操作会直接失败:

  • pg_basebackup:任何使用 -xs(流式 wal)的 pg_basebackup 将因无法发送 timeline_history 命令而失败。
  • 使用流复制构建备库:备库启动时无法从主库获取所需的时间线历史文件,导致复制失败。
  • pitr(时间点恢复):恢复过程无法确定时间线的完整分叉关系,导致恢复无法进行。
  • pg_rewind:工具因无法找到必要的时间线历史文件而失败。

报错示例

执行 pg_basebackup 时的典型错误信息:

pg_basebackup: error: could not send replication command "timeline_history": 
error:  could not open file "pg_wal/00000009.history": no such file or directory
30203/30203 kb (100%), 0/1 tablespace (...bak_20260429_2/global/pg_control)
30203/30203 kb (100%), 0/1 tablespace (...bak_20260429_2/global/pg_control)
30203/30203 kb (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 4/35000100
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: error: child thread exited with error 1
pg_basebackup: removing contents of data directory "/data/highgo/hgdbbak/dbbak/hgdbbak_20260429_2"

该错误表明备份开始时当前时间线为 9,pg_basebackup 需要通过复制协议从主库获取 00000009.history,但由于文件丢失,请求失败。

  为什么数据库能正常运行,备份却失败? 这是运维人员最容易误解的地方。数据库日常运行依赖的是 wal 段文件,而备份时 pg_basebackup 需要为备份创建一份完整的时间线上下文。原因在于:备份文件在压缩传送之前,必须先完整记录当前的时间线谱系。只有保存了完整的 *.history 文件,将来基于该备份执行恢复时才能正确重放跨时间线的 wal 段。因此,pg_basebackup 强制要求读取当前时间线的 .history 文件。

五、常见疑问

5.1 备库上的 .history 文件数量与主库不一致,是否异常?

完全正常。 备库由某个时间点的物理备份搭建而来,只继承该备份对应的时间线历史,后续通过流复制接收 wal 段同步数据,但不会同步主库的 .history 文件。因此,主备节点之间 .history 文件数量不一致是设计特性,而非异常。

5.2 手动构造 .history 文件不可取

虽然从技术上讲,.history 文件的格式相对简单,可以手动构造,但这种方法存在诸多风险:

  • 难以确定准确的分叉点 lsn:lsn 是二进制 wal 记录中的精确位置,手动猜测极易出错;
  • 缺少必要的上下文信息:即便构造了文件,也无法保证与 pg_control 中存储的快照信息完全一致;
  • 潜在的数据不一致:错误的时间线历史可能导致恢复失败或 wal 重放错乱。

生产环境切勿采用手动构造的方式。

六、恢复方案

情形方案说明
有归档或备份副本.history 文件从归档目录(或其他备份)复制回 pg_wal/ 目录。这是最安全、最推荐的恢复方式。
无归档副本,但熟悉环境历史仅限测试环境或了解确切时间线关系的应急方案:可手动构造 .history 文件,按格式准确填写父时间线和分叉点信息。生产环境不推荐此方案。
无法找回文件最近一次完整且可靠的物理全量备份恢复整个数据目录。这是唯一可以保证数据一致性的可靠方式。
逻辑备份pg_dump / pg_dumpall 不依赖 .history 文件,不会报错。但逻辑备份无法用于物理备库搭建或 pitr 增量恢复,属于不同维度的备份方案。

七、预防措施

核心原则:不要手动删除 pg_wal/ 目录下的任何文件。

具体方案

  • 启用 wal 归档:配置 archive_command 将所有 wal 段文件及 .history 文件归档到独立的归档目录。归档目录是 .history 文件最重要的安全保障,也是恢复时唯一可依赖的副本来源。
  • 安全清理归档目录:若需清理归档目录,使用 pg_archivecleanup 工具。该工具可安全删除归档目录中不再需要的 wal 文件及 .backup 文件,但不会也不能删除 pg_wal 目录下的 .history 文件——因为数据库正常运行需要这些文件在 pg_wal 目录中存在。
  • 禁止直接操作 pg_wal:任何维护脚本都应避免直接删除 pg_wal 下的任何文件。若需清理磁盘空间,应清理归档目录而非 pg_wal
  • 明确区分清理工具:pg_archivecleanup -b-b 参数专门用于清理归档目录中的 .backup 文件,并非用于删除 pg_wal 中的 .history 文件。切勿混淆两者的用途。
  • 定期检查归档完整性:周期性执行归档目录与 pg_wal 目录的文件对照检查,可及早发现 .history 文件的意外丢失。

特别提醒:不要尝试“绕过”文件检查

  一个常见的误区是尝试修改 pg_basebackup 参数以“跳过”时间线历史文件的检查。这种做法并不可行——timeline_history 命令是 postgresql 内部复制协议的核心请求,任何物理备份工具都必须完成时间线信息的返回与验证,才能确保备份在将来恢复时不会因缺少必要的 wal 上下文而完全失效。

到此这篇关于postgresql .history 文件详解的文章就介绍到这了,更多相关postgresql .history 文件内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com