主庫(kù)上WAL被覆蓋導(dǎo)致備庫(kù)不可用

1、問(wèn)題現(xiàn)象

當(dāng)一個(gè)異步流復(fù)制備庫(kù)主機(jī)由于硬件故障,需要做一次停機(jī)硬件檢測(cè),停機(jī)檢測(cè)之后再次啟動(dòng)備庫(kù),啟動(dòng)后報(bào)如下錯(cuò)誤:

CST,"repuser","",11005,"10.0.0.16:41020",5d31667d.2afd,4,"idle",2020-12-06
14:43:09	CST,4/0,0,ERROR,58P01,"requested	WAL	segment 	000000010000000000000033 has already been removed

以上錯(cuò)誤是指?jìng)鋷?kù)所需的WAL日志文件 000000010000000000000033 被清除。由于異步流復(fù)制備庫(kù)關(guān)閉,在此期間主庫(kù)無(wú)法將WAL日志流發(fā)送給備庫(kù),備庫(kù)關(guān)閉期間產(chǎn)生的WAL保存在主庫(kù)的WAL目錄里,若主庫(kù)的wal_keep_segments設(shè)置比較小,主庫(kù)可能會(huì)覆蓋并循環(huán)使用還沒(méi)有發(fā)送給備庫(kù)的WAL日志,若主庫(kù)沒(méi)有歸檔,這種情況只能重做備庫(kù),對(duì)于數(shù)據(jù)量較大的數(shù)據(jù)庫(kù),重做備庫(kù)的時(shí)間會(huì)很長(zhǎng)。

2、解決方案

(1)流復(fù)制斷開(kāi),先看進(jìn)程是否存在,主庫(kù)看wal sender,備庫(kù)看receiver進(jìn)程,發(fā)現(xiàn)都不存在,說(shuō)明流復(fù)制已經(jīng)斷開(kāi)。

(2)查看備庫(kù)最近錯(cuò)誤日志,在 data 目錄下的 hg_log 目錄,找到最近的相關(guān)報(bào)錯(cuò)日志,發(fā)現(xiàn)主庫(kù)的wal 日志已經(jīng)被移除。

(3)流復(fù)制的備庫(kù)是通過(guò) wal receiver 進(jìn)程獲取相關(guān)的 wal 日志來(lái)進(jìn)行應(yīng)用達(dá)到主備的一致,因此主庫(kù)上的 wal 日志被移除,備庫(kù)無(wú)法繼續(xù)進(jìn)行應(yīng)用相關(guān) wal,所以流復(fù)制斷開(kāi)。

(4)此種情況只能通過(guò)重做備庫(kù)來(lái)恢復(fù)流復(fù)制,使用 pg_basebackup 命令對(duì)備庫(kù)進(jìn)行重做,但需要注意,因?yàn)閜g_basebackup占用資源較大,若數(shù)據(jù)量較大,請(qǐng)選擇在夜間業(yè)務(wù)不繁忙時(shí)重做備庫(kù)。

(5)先關(guān)閉備庫(kù)并將 data 目錄改為 data1。

[highgo@localhost 4.5]$ pg_ctl stop
[highgo@localhost 4.5]$ cd $PGHOME
[highgo@localhost 4.5]$ mv data data1

tp

(6)重做備庫(kù),ip 改為主庫(kù)相關(guān) ip,目錄改為備庫(kù)相關(guān)目錄。

tp

(7)此時(shí)備庫(kù)已經(jīng)重做,流復(fù)制已恢復(fù)。

三種方法應(yīng)對(duì)上述情況:
1)將主備庫(kù) wal_keep_segments 參數(shù)設(shè)置為較大值,從而保證$PGDATA/pg_wal目錄下留存較多的WAL日志,主庫(kù) WAL日志留存越多,允許備庫(kù)宕機(jī)的時(shí)間越長(zhǎng),設(shè)置此參數(shù)時(shí)注意不要將pg_wal目錄撐滿;

2)主庫(kù)上開(kāi)啟歸檔,如沒(méi)有足夠的硬盤空間保留WAL歸檔,至少在備庫(kù)停機(jī)維護(hù)時(shí)臨時(shí)開(kāi)啟主庫(kù)歸檔,這樣當(dāng)備庫(kù)啟動(dòng)時(shí),若所需的WAL被主庫(kù)循環(huán)清理掉,至少可從歸檔里獲取所需的WAL文件,這樣比重做備庫(kù)省時(shí)省力得多;

3)主庫(kù)設(shè)置復(fù)制槽。設(shè)置復(fù)制槽之后流復(fù)制主庫(kù)將獲得備庫(kù)的復(fù)制狀態(tài),即使備庫(kù)宕機(jī)主庫(kù)也可獲得備庫(kù)的復(fù)制狀態(tài)。因此,當(dāng)流復(fù)制備庫(kù)宕機(jī)時(shí),主庫(kù)不會(huì)覆蓋掉備庫(kù)還沒(méi)有接收的WAL。若備庫(kù)停機(jī)時(shí)間太長(zhǎng),主庫(kù)的pg_wal目錄將有可能被撐滿,建議將pg_wal目錄單獨(dú)放在大容量硬盤上。

?