爲什麼要慎用replication slot

複製槽概念

複製槽(replication slot)在postgresql9.4版本中被引入,引入之初是爲了防止備庫需要的xlog日誌在主庫被刪除,主庫會會根據備庫返回的信息確認哪些xlog已不再需要,,才能進行清理。同時主庫不會移除那些導致恢復衝突的行,關於恢復衝突,前面有一篇文章講到過可以通過設置hot_standby_feedback、max_standby_streaming_delay等參數進行預防,但是這些參數只有在主備關係正常時才能起到作用,而replication slot能夠確保在主備斷連後主庫的xlog仍不被清理。

複製槽分爲物理複製槽physical replication slot和邏輯複製槽logic replication slot。物理複製槽一般結合流複製一起使用,能夠很好的保證備庫需要的日誌不會在主庫刪除,本文重點討論邏輯複製槽。

Logic replication slots一般被用於邏輯異步複製,一個很好的應用就是用於異構數據庫之間的邏輯複製。大致原理是將源端xlog進行解碼,解析成具體sql,然後到目標端進行回放。支持邏輯解碼需要將wal_level設置爲logic,logic會在replica的基礎上增加一些信息以支持邏輯解碼,該模式會增大wal日誌的數量,尤其是大量的update,delete操作的庫。
在這裏插入圖片描述

邏輯複製槽的出現算是一個創新,相當於官方將xlog解碼功能提供到源碼中,這是做邏輯同步工具公司的福音,公司只需要使用pg_recvlogic等邏輯解碼工具或pg_logic_slot_get_changes()等SQL接口函數將xlog解析成sql文本在目標端回放即可。

需要關注的問題

對於邏輯複製槽,有下面幾點需要注意:

①一個邏輯複製槽只能解碼一個database,但是一個database可以有多個複製槽進行解碼,同一個複製槽可能同時有多個接收端進行訂閱。

②複製槽的消息只發送一次,同時它不關心接收端的狀態,如果接收端執行失敗,那麼複製槽不會向前推進,接收端成功後繼續從上次失敗的位點繼續進行消費。

③不支持DDL、列存、壓縮表的解碼,DDL一般需要需要創建額外的觸發器來進行處理,但可以做到表級訂閱。

④邏輯複製不能保證數據不丟失,不能用作數據容災,但是可以用於數據遷移,在主庫有大事務的情況下延遲較大。

⑤不使用的複製槽一定要及時刪除。

慎用replication slot

上面的第五點是需要特別注意的,也是我說慎用replication slot的原因。

筆者在生產環境多次遇到因爲邏輯複製槽造成xlog堆積的問題。我們知道當主備斷連的時候邏輯槽會保證主庫不清理xlog,這樣就會造成xlog堆積。其實不僅是主備斷連,當主庫沒有更新業務的時候,主庫的xlog也不會清理,有些人可能會說了,主庫都沒有業務了,根本就不會生成xlog,那麼也不會有xlog堆積的問題了,看似解釋很完美,但是我們試想下面這個場景。

如果是多租戶的環境呢?如果我在使用一個集羣,比如pgxc,集羣上有多個數據庫,我們爲了保證rpo接近0,使用了邏輯複製的方案,其中有兩個庫都需要同步,需要建立兩個邏輯槽。如果其中一個業務很繁忙,每天有大量的跑批操作,但是另一個庫不是那麼繁忙,或者說在節假日的時候沒有業務,這時就需要特別小心了。因爲兩個庫其實共用的是一份xlog日誌,其中一個庫很麻煩產生大量的xlog,但是另一個庫沒有業務,會造成該庫的邏輯槽的restart_lsn始終不往前推進,這樣就造成主庫的xlog沒法刪除,最終造成主庫的磁盤爆掉。筆者生產環境中曾經遇到過xlog堆積好幾萬個的情況,好在當時磁盤容量夠大,沒有發生事故。
在這裏插入圖片描述

最佳實踐

所以在生產環境中如果使用replication slot,有下面幾點建議:

①可以增加xlog日誌個數的監控,當xlog數量超過正常值時通知dba查找原因。

②做好對每個複製槽同步狀態的監控,出現某個槽同步狀態異常要及時處理,同步異常會造成lsn不向前推進。

③對於業務很空閒但是數據需要同步的庫,可以自定義腳本,定期更新無用表,手工推進lsn。

④如果xlog已經堆積很多磁盤馬上要爆炸的情況下,在考慮應急刪掉複製槽之前要評估剩餘空間是否還有足夠富餘,因爲即使刪掉複製槽,xlog也不是馬上就會清理,刪掉後主庫vacuum也會產生較多xlog日誌,一定要做好評估。

⑤增加pg_replication_slot()視圖中restart_lsn的監控,對於落後較大和長期不推進的lsn進行告警。

好吧,加油吧。
歡迎關注我的公衆號:數據庫架構之美

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章