PostgreSQL主從流複製原理及搭建

Postgresql9開始支持流複製(stream replication),作爲pg原生的複製技術,有着很好的性能。本文從幾個方面全面介紹pg的流複製技術。

主從部署

Postgresql主從部署比較簡單,首先你需要安裝好主從兩個實例,然後進行主備庫配置,主要配置可以參考如下步驟:

主庫配置:
①創建角色用於同步:
create role replica login replication encrypted password 'replica';
②增加pg_hba配置:
host     all     all     192.168.1.2/32    trust
host	 replication	replica		192.168.1.2/32(從庫ip)	md5
③配置postgresql.conf
listen_addresses='*'
archive_mode = on
archive_command = 'test ! -f /postgresarch/%f && cp %p /postgresarch/%f'
synchronous_standby_names='FIRST 1 (s1,s2,s3)'
max_connections從庫要大於主庫
④重啓服務器。

從庫配置:
①基礎備份:
刪除從庫data目錄
pg_basebackup -h 192.168.1.1 -U replica -D /postgresdata/pginst1/ -X stream -P
②配置從庫數據目錄recovery.conf
standby_mode = 'on'
primary_conninfo = 'host=192.168.1.1 port=5432 user=replica password=replica application_name=s1'
recovery_target_timeline = 'latest'

同步流程

下面這個圖描述了postgresql主從流複製的流程。
在這裏插入圖片描述
主要分爲以下幾個流程:
①主備數據庫啓動,備庫啓動walreceiver進程,wal進程向主庫發送連接請求。
②主庫收到連接請求後啓動walsender進程,並與walreceiver進程建立tcp連接。
③備庫walreceiver進程發送最新的wal lsn給主庫。
④主庫進行lsn對比,定期向備庫發送心跳信息來確認備庫可用性,並且將沒有傳遞的wal日誌進行發送,同時調用SyncRepWaitForLSN()函數來獲取鎖存器,並且等待備庫響應,鎖存器的釋放時機和主備同步模式的選擇有關,同步模式這塊內容下面再說。
④備庫調用操作系統write()函數將wal寫入緩存,然後調用操作系統fsync()函數將wal刷新到磁盤,然後進行wal回放。同時備庫向主庫返回ack信息,ack信息中包含write_lsn、flush_lsn、replay_lsn,這些信息會發送給主庫,用以告知主庫當前wal日誌在備庫的應用位置及狀態,相關位置信息可以通過pg_stat_replication視圖查看。
⑤如果啓用了hot_standby_feedback參數,備庫會定期向主庫發送xmin信息,用以保證主庫不會vacuum掉備庫需要的元組信息。關於該參數的詳細解釋,可以參考我的上一篇文章。

同步模式

Postgresql數據庫提供了五種同步模式,相比商業數據庫還是很強大的。同步模式主要由synchronous_commit參數控制。下面簡單介紹一下五種同步模式的區別。下面這張圖很清晰地描述了流複製的幾種模式:

在這裏插入圖片描述
off:對於本機wal不用寫到磁盤就可以提交,是異步模式,存在數據丟失風險。
local:不管有沒有備庫只需要保證本機的wal日誌刷到磁盤就行。
remote_write:等待主庫日誌刷新到磁盤,同時日誌傳遞到備庫的操作系統緩存中,不需要刷盤就能提交,不能避免操作系統崩潰。
on:如果沒有備庫,表示wal日誌需要刷新到本地的磁盤中才能提交,如果存在同步備庫時(synchronous_standby_name不爲空),需要等待遠程備庫也刷新到磁盤主庫才能提交。
remote_apply:pg高版本纔出來的功能,備庫刷盤並且回放成功,事務被標記爲可見,用於做負載均衡,讀寫分離等。

相關參數

wal_level:
wal日誌級別,這個參數決定了有多少信息寫入wal日誌,默認是replica,這種模式支持複製和wal歸檔,同時支持備庫只讀查詢。
minimal:除了實例crash恢復需要的記錄,其他不記錄,比如CREATE TABLE AS,CREATE INDEX,CLUSTER,COPY可以跳過,該模式記錄的日誌信息不足以支持wal歸檔和流複製。
logic:在replica的基礎上增加一些信息以支持邏輯解碼,該模式會增大wal日誌的數量,尤其是大量的update,delete操作的庫。
在9.6之前還有archive和hot_standby模式,映射到現在的replica模式。

synchronous_commit:
五種同步模式選擇,前面已經說過。關於生產環境配置我也做過測試,如果單併發插入remote_write和on性能差距十倍,但是高併發的情況下,差距不大,所以刷盤其實是比較消耗性能的操作,生產環境中建議選用remote_write。

synchronous_standby_names:
在主庫上配置,備機的複製列表。有下面幾種種方式(s1,s2,s3代表備機的application_name,配置在recovery.conf中):
synchronous_standby_names=‘s1’ 代表s1備機返回就可以提交。
synchronous_standby_names=‘FIRST 2 (s1,s2,s3)’ 代表s1,s2,s3三個備機中前兩個s1和s2返回主庫就可以提交。
synchronous_standby_names=‘ANY 2 (s1,s2,s3)’ 代表s1,s2,s3三個備機中任意兩個備機返回主庫就可以提交,基於quorum協議。
synchronous_standby_names=’*’ *代表匹配任意主機,也就是任意主機返回就可以提交。

vacuum_defer_cleanup_age:
指定vacuum延遲清理的事務數,即vacuum和vacuum full操作不會立即清理剛剛被刪除元組。至於爲什麼要延遲清理,我的上一篇文章有講到。

max_wal_senders:
指定wal日誌發送進程的最大併發連接數。設爲0表示禁用replication,參數必須小於max_connections-superuser_reserved_connections

checkpoint_segments(9.5之前):
自動wal checkpoint間隔時間段內最多產生的wal數量。9.5之前纔有這個參數,9.5後廢除了這個參數,新增了max_wal_size,改爲通過max_wal_size和checkpoint_completion_target共同控制,計算公式爲:checkpoint_segments=max_wal_size/(2+checkpoint_completion_target),所以checkpoint_segments大概爲wal_max_size的1/3到1/2。

wal_keep_segments:
設置“pg_xlog”目錄下保留事務日誌文件的最小數目用於流複製,如果備機停機時間過長導致主庫xlog被刪除,那麼主備關係會失敗,但是如果開啓了歸檔,備機可以從歸檔日誌中繼續恢復。

min_wal_size:
只要wal日誌目錄使用空間小於該值,那麼舊的wal日誌就會循環使用而不是進行刪除。這個參數是爲了確保足夠的wal空間預留給突發情況,比如大的跑批操作。

max_standby_archive_delay、max_standby_streaming_delay、hot_standby_feedback:
控制備機查詢衝突的參數,上一篇文章說過,這裏不再贅述。

wal_receiver_status_interval:
備機向主機發送相關複製信息的最小頻率,包含相關lsn信息,可以通過pg_stat_replication視圖查看。

wal_recevier_timeout、wal_recevier_retry_interval:
控制連接超時時間,很好理解,不再贅述。

我們可以通過pg_stat_replication,pg_stat_wal_receiver,pg_current_wal_lsn,pg_last_wal_receive_lsn這幾個視圖查看複製的狀態信息。

總體來說流複製的內容比較簡單,本文只是從基礎知識層面介紹了流複製的原理與簡單配置。

技術永無止境,加油吧。

歡迎關注我的公衆號:數據庫架構之美

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