在某些場景中,使用者可能需要部署延遲的資料庫,比如用來應對誤操作。
使用者可以建立延遲2小時的standby資料庫,如果在2小時内發現了誤操作,可以直接使用hot standby,檢視誤操作前的資料,進而進行恢複。
而不需要對資料庫進行pitr恢複操作。
當然這個防範左右還有更好的方法,比如使用我前面寫的基于zfs的快照的備份政策,也可以快速的回檔。
好了言歸正傳,為什麼要小心使用postgresql延遲hot standby,如果你的standby不僅僅要延遲,還要用于查詢的話,那就需要注意了。

在postgresql的redo中,隻在commit, abort的record中記錄了時間戳,是以目前postgresql的延遲備庫,隻能在apply事務結束的redo上面做時間的延遲控制。
在recovery.conf中也能看到這個描述
了解了postgresql的延遲恢複原理後,回答一下這麼做會有什麼問題呢?
比如某個事務包含了ddl操作,那麼這筆操作馬上會在hot standby執行,鎖在hot standby也同時被加載。
但是當遇到這個事務的commit record時,由于設定了recovery_min_apply_delay,這筆record被延遲執行,這個鎖也會延遲到這筆record被apply為止。
在此延遲時間段内,對這個被執行ddl的表的query都會被堵塞。
這個鎖會持續多長時間呢?
這麼長recovery_min_apply_delay。
其他鎖和讀操作基本上都沒有沖突,是以使用者在延遲的hot_standby查詢資料時感覺不到,但是ddl的感覺是非常明顯的。
1. 增加guc參數,apply時,檢測事務中是否包含ddl級别的鎖,如果包含這種鎖,使用者可以通過recovery.conf中的參數設定,這個事務的record是否立即執行,而不等待recovery_min_apply_delay。
減少延遲hot standby中事務包含ddl鎖帶來的問題。
2. 或者增加對事務開啟時間的記錄,使用者可以通過guc參數,設定延遲是從事務開始時間計算,還是從事務結束開始計算。
1. 建議使用者不要使用帶延遲的hot_standby作為常用的隻讀備庫,至少在改進之前不要這麼做。
如果你僅僅想做一個誤操作保護的話,這麼做是沒有問題的。