PostgreSQL .history 文件詳解
一、什么是 .history 文件?
.history 文件是 PostgreSQL 的時間線歷史文件(Timeline History File),位于 $PGDATA/pg_wal/ 目錄下(PostgreSQL 10 之前為 pg_xlog),文件命名格式為 000000XX.history(例如 00000009.history),其中 XX 為八位十六進制表示的時間線 ID(Timeline ID)。在 PostgreSQL 運維中,.history 文件是一個雖不起眼卻至關(guān)重要的元數(shù)據(jù)文件。它僅在時間線發(fā)生分叉時才產(chǎn)生,但一旦被誤刪,就會導致 pg_basebackup 備份失敗、物理備庫無法重建等一系列連鎖反應。
它是一個純文本文件,每一行記錄一次時間線切換事件,格式如下:
<parentTLI> <switchpoint> <reason>
- parentTLI:父時間線 ID;
- switchpoint:產(chǎn)生分叉的 WAL 位置(LSN);
- reason:產(chǎn)生時間線分叉的原因說明(如
no recovery target specified)。
一個典型的 00000002.history 文件內(nèi)容如下:
1 0/A000198 before 2018-7-9 12:05:00.861324+00
每一行都代表一次時間線分裂事件,記錄了當前時間線是從哪條時間線、在哪個 WAL 位置分叉出來的,以及分叉的原因。
內(nèi)容中的“原因”條目
reason 字段的具體取值取決于時間線切換的觸發(fā)方式:
- PITR 完成時:
reason通常顯示no recovery target specified或恢復目標相關(guān)的描述,標明恢復的邊界條件。 - 備庫提升(Promote)時:
reason可能涉及提升操作的相關(guān)上下文信息。 pg_rewind操作:reason會體現(xiàn)pg_rewind導致的 timeline 調(diào)整。
需要注意的是,不同 PostgreSQL 版本中的 reason 字段格式可能存在細微差異,但每條記錄都至少包含父時間線 ID 和分叉點 LSN 這兩個核心要素。
二、時間線(Timeline)
理解 .history 文件,必須先了解 PostgreSQL 的時間線概念。這一概念從 PostgreSQL 8.0 開始引入,旨在解決 PITR(Point-In-Time Recovery,時間點恢復)中的 WAL 覆蓋問題??紤]如下場景:管理員將數(shù)據(jù)庫恢復到業(yè)務受損前的某個時間點后繼續(xù)運行。若仍沿用原時間線,新生成的 WAL 文件將與舊 WAL 文件同名,導致原有的 WAL 記錄被覆蓋,無法再次恢復到其他時間點。為解決這一問題,PostgreSQL 引入了時間線機制。每當數(shù)據(jù)庫集簇通過恢復啟動后繼續(xù)運行時,PostgreSQL 都會切換到一條新的時間線——新生成的時間線 ID 在舊的時間線 ID 基礎上加 1,并且生成一個 .history 文件記錄本次分叉的完整信息。WAL 文件名本身包含時間線 ID(前 8 位十六進制數(shù)),這一設計保證了新的時間線不會覆蓋舊時間線產(chǎn)生的 WAL 文件。因此,時間線是進行精確 PITR、搭建多級備庫等操作的核心基石。
2.1 關(guān)于時間線切換的觸發(fā)時機
一個常見的理解偏差是認為“每次備庫提升為主庫都會產(chǎn)生一條新的時間線”。這種說法并非完全錯誤,但需要明確兩點:
- 單純的主備復制過程中不會產(chǎn)生時間線切換。備庫僅僅回放主庫發(fā)送的 WAL 記錄,始終運行在與主庫相同的時間線上。
- 時間線切換發(fā)生在以下兩種情況:
- 對備庫執(zhí)行
pg_ctl promote命令,將其提升為獨立的可寫主庫; - 基于 PITR(時間點恢復)將數(shù)據(jù)庫恢復到過去某一時刻,然后讓數(shù)據(jù)庫以讀寫模式繼續(xù)運行。
- 對備庫執(zhí)行
無論是在 PostgreSQL 12 之前的 recovery.conf 中設置 promote 或 recovery_target_timeline,還是在新版本的 postgresql.conf 中配置相關(guān)參數(shù),其本質(zhì)都是恢復過程結(jié)束后數(shù)據(jù)庫重新啟動這一動作觸發(fā)了時間線的新建。
2.2 關(guān)于版本差異的特別說明
PostgreSQL 12 及以后版本中,recovery.conf 文件的功能已被整合到主配置文件 postgresql.conf 或 postgresql.auto.conf 中,但時間線切換的觸發(fā)機制并未改變。
三、.history 文件的核心作用
.history 文件在以下三個核心場景中發(fā)揮作用:
- PITR(時間點恢復):恢復時,PostgreSQL 需要讀取
.history文件,結(jié)合recovery_target_timeline參數(shù)來確定目標時間線的完整分支路徑。 - 流復制協(xié)議與備庫構(gòu)建:當使用
pg_basebackup或流復制啟動時,PostgreSQL 需要通過復制協(xié)議讀取主庫的.history文件,以便備庫理解主庫完整的時間線譜系。 - pg_rewind:
pg_rewind工具依賴時間線歷史文件來判斷源集簇和目標集簇的分叉點,從而將舊主庫同步至新時間線。
四、.history 文件缺失的影響
.history 文件缺失對數(shù)據(jù)庫日常運行無直接影響。 數(shù)據(jù)庫常規(guī)事務處理、checkpoint、WAL 切換等操作依賴 WAL 段文件,不依賴 .history 文件。因此,刪除了 .history 文件,數(shù)據(jù)庫可以繼續(xù)正常運行——這也是該文件易被忽視的重要原因。
受影響的操作
一旦 .history 文件被誤刪,以下操作會直接失?。?/p>
pg_basebackup:任何使用-Xs(流式 WAL)的pg_basebackup將因無法發(fā)送TIMELINE_HISTORY命令而失敗。- 使用流復制構(gòu)建備庫:備庫啟動時無法從主庫獲取所需的時間線歷史文件,導致復制失敗。
- PITR(時間點恢復):恢復過程無法確定時間線的完整分叉關(guān)系,導致恢復無法進行。
pg_rewind:工具因無法找到必要的時間線歷史文件而失敗。
報錯示例
執(zhí)行 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 需要通過復制協(xié)議從主庫獲取 00000009.history,但由于文件丟失,請求失敗。
為什么數(shù)據(jù)庫能正常運行,備份卻失??? 這是運維人員最容易誤解的地方。數(shù)據(jù)庫日常運行依賴的是 WAL 段文件,而備份時 pg_basebackup 需要為備份創(chuàng)建一份完整的時間線上下文。原因在于:備份文件在壓縮傳送之前,必須先完整記錄當前的時間線譜系。只有保存了完整的 *.history 文件,將來基于該備份執(zhí)行恢復時才能正確重放跨時間線的 WAL 段。因此,pg_basebackup 強制要求讀取當前時間線的 .history 文件。
五、常見疑問
5.1 備庫上的 .history 文件數(shù)量與主庫不一致,是否異常?
完全正常。 備庫由某個時間點的物理備份搭建而來,只繼承該備份對應的時間線歷史,后續(xù)通過流復制接收 WAL 段同步數(shù)據(jù),但不會同步主庫的 .history 文件。因此,主備節(jié)點之間 .history 文件數(shù)量不一致是設計特性,而非異常。
5.2 手動構(gòu)造 .history 文件不可取
雖然從技術(shù)上講,.history 文件的格式相對簡單,可以手動構(gòu)造,但這種方法存在諸多風險:
- 難以確定準確的分叉點 LSN:LSN 是二進制 WAL 記錄中的精確位置,手動猜測極易出錯;
- 缺少必要的上下文信息:即便構(gòu)造了文件,也無法保證與 pg_control 中存儲的快照信息完全一致;
- 潛在的數(shù)據(jù)不一致:錯誤的時間線歷史可能導致恢復失敗或 WAL 重放錯亂。
生產(chǎn)環(huán)境切勿采用手動構(gòu)造的方式。
六、恢復方案
| 情形 | 方案 | 說明 |
|---|---|---|
| 有歸檔或備份副本 | 將 .history 文件從歸檔目錄(或其他備份)復制回 pg_wal/ 目錄。這是最安全、最推薦的恢復方式。 | |
| 無歸檔副本,但熟悉環(huán)境歷史 | 僅限測試環(huán)境或了解確切時間線關(guān)系的應急方案:可手動構(gòu)造 .history 文件,按格式準確填寫父時間線和分叉點信息。生產(chǎn)環(huán)境不推薦此方案。 | |
| 無法找回文件 | 從最近一次完整且可靠的物理全量備份恢復整個數(shù)據(jù)目錄。這是唯一可以保證數(shù)據(jù)一致性的可靠方式。 | |
| 邏輯備份 | pg_dump / pg_dumpall 不依賴 .history 文件,不會報錯。但邏輯備份無法用于物理備庫搭建或 PITR 增量恢復,屬于不同維度的備份方案。 |
七、預防措施
核心原則:不要手動刪除 pg_wal/ 目錄下的任何文件。
具體方案
- 啟用 WAL 歸檔:配置
archive_command將所有 WAL 段文件及.history文件歸檔到獨立的歸檔目錄。歸檔目錄是.history文件最重要的安全保障,也是恢復時唯一可依賴的副本來源。 - 安全清理歸檔目錄:若需清理歸檔目錄,使用
pg_archivecleanup工具。該工具可安全刪除歸檔目錄中不再需要的 WAL 文件及.backup文件,但不會也不能刪除pg_wal目錄下的.history文件——因為數(shù)據(jù)庫正常運行需要這些文件在pg_wal目錄中存在。 - 禁止直接操作
pg_wal:任何維護腳本都應避免直接刪除pg_wal下的任何文件。若需清理磁盤空間,應清理歸檔目錄而非pg_wal。 - 明確區(qū)分清理工具:
pg_archivecleanup -b的-b參數(shù)專門用于清理歸檔目錄中的.backup文件,并非用于刪除pg_wal中的.history文件。切勿混淆兩者的用途。 - 定期檢查歸檔完整性:周期性執(zhí)行歸檔目錄與
pg_wal目錄的文件對照檢查,可及早發(fā)現(xiàn).history文件的意外丟失。
特別提醒:不要嘗試“繞過”文件檢查
一個常見的誤區(qū)是嘗試修改 pg_basebackup 參數(shù)以“跳過”時間線歷史文件的檢查。這種做法并不可行——TIMELINE_HISTORY 命令是 PostgreSQL 內(nèi)部復制協(xié)議的核心請求,任何物理備份工具都必須完成時間線信息的返回與驗證,才能確保備份在將來恢復時不會因缺少必要的 WAL 上下文而完全失效。
到此這篇關(guān)于PostgreSQL .history 文件詳解的文章就介紹到這了,更多相關(guān)PostgreSQL .history 文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于PostgreSQL pg_hba.conf 配置參數(shù)的使用說明
這篇文章主要介紹了基于PostgreSQL pg_hba.conf 配置參數(shù)的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
Postgresql數(shù)據(jù)庫SQL字段拼接方法
Postgresql里面內(nèi)置了很多的實用函數(shù),下面這篇文章主要給大家介紹了關(guān)于Postgresql數(shù)據(jù)庫SQL字段拼接方法的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-11-11
postgresql關(guān)于like%xxx%的優(yōu)化操作
這篇文章主要介紹了postgresql關(guān)于like%xxx%的優(yōu)化操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
PostgreSQL大規(guī)模隨機數(shù)據(jù)生成的完整指南
本文詳細介紹了使用PostgreSQL自帶的generate_series和random()函數(shù)家族快速生成大規(guī)模測試數(shù)據(jù)的方法和技巧,涵蓋基礎用隨機函數(shù)、典型應用場景、性能優(yōu)化、第三方工具推薦、實戰(zhàn)案例及注意事項,需要的朋友可以參考下2026-05-05
postgresql 切換 log、xlog日志的實現(xiàn)
這篇文章主要介紹了postgresql 切換 log、xlog日志的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01

