為什麼我的 postmaster 程序(有時)在 WAL 基礎恢復後變得無法管理?
TL;DR:在從 WAL 基本備份恢復其數據目錄後立即啟動 Postgres 時,會產生不可停止、無法使用的 postmaster。為什麼?
語境:
我們使用 PGDG 包在 CentOS 6 上執行 postgresql 8.4。我們有一個用於開發人員測試環境的腳本,用於恢復生產伺服器數據目錄的夜間備份(在呼叫
pg_start_backup
和之間創建pg_stop_backup
)。該腳本解壓縮文件,並用於restore_command
重新應用在生產中進行備份期間生成的任何 WAL。它通常可以正常工作,並且恢復速度比基於 SQL 的
pg_dump
‘ed 文件恢復快數百倍。問題:
有時,在解壓數據目錄後,腳本會通過執行啟動 postgres
/etc/init.d/postgresql start
(這是指向 . 的符號連結/etc/init.d/postgresql-8.4
。這使它成為我們最終升級到 9.* 時可預測的初始化腳本)。它報告“OK”,如:它正確啟動。然後 WAL 不會恢復;它無限期地掛起等待recovery.done
文件出現。我試過的:
當我
/etc/init.d/postgresql status
在無限期掛起期間執行時,初始化腳本報告dead but pid file exists
.然後我跑了
ps -ef | grep post
。奇怪的是,postmaster 程序和歸檔器等正在執行。所有呼叫參數都是正確的(正確的 datadir 等)。當我執行
psql
時,它檢測到一個正在執行的 postmaster 和一個初始化的postgres
數據庫,但沒有檢測到主數據庫——我們關心通過 WAL 腳本恢復的那個。然後我檢查了數據目錄上的權限,一切看起來都很好。
執行
/etc/init.d/postgresql stop
報告“OK”,並終止歸檔程序/觀察程序程序,但 postmaster 保持執行。我嘗試時也發生了同樣的事情
killall -r '*.postmaster*.'
。唯一可以恢復卡住的 WAL 恢復的是
killall -s 3 -r '.*postmaster.*'
(信號 3 是 SIGQUIT),然後是/etc/init.d/postgresql start
.我在無法管理的狀態下檢查
pg_startup.log
了每日文件pg_log
,一切看起來都很好。pg_startup.log
將成功啟動註冊為最後一個條目。可能的原因:
關於我們的配置,有一些(我認為是次要的)事情是非標準的。
- 正如我之前所說,我們的 init 腳本符號連結到一個與版本無關的腳本,位於
/etc/init.d/postgresql
. 這指向我們想要的任何地方。目前它指向/etc/init.d/postgresql-8.4
.- 我們的
postgresql.conf
文件位於/etc/
(具有 postmaster 使用者的所有者和組),並具有指向數據目錄的符號連結。我們的 WAL 恢復腳本確保在嘗試啟動 postgres 之前重新創建符號連結。- 我們最近將基礎架構從 Postgresql 8.4.11 升級到了 8.4.12。我們正在測試新版本的穩定性。我們的生產伺服器正在執行 8.4.11。但是,我們通過 將數據從它們中提取出來,對其進行
pg_dump
清理,然後將其“打包”以在其他地方(在 8.4.12 上)進行 WAL 恢復,因此我們不會跨不兼容的 Postgres 版本恢復 WAL。題:
為什麼要這樣做?下面列出的可能原因之一可能是罪魁禍首嗎?
一般來說,如果您遇到此類問題,最好將它們放在 pgsql-bugs 列表中。那裡的人可以幫助弄清楚要收集哪些資訊,以幫助確定這種不當行為的範圍並幫助您解決問題。
8.4.11 到 8.4.12 wal 還原也應該可以正常工作。
如果這只是偶爾發生,我認為您的解釋不會到達那裡。這聽起來確實可以由可以確定是否需要程式碼修復的人使用額外的故障排除。