PostgreSQL技術大講堂 - 第43講:流復制原理
最新學訊:近期OCP認證正在報名中,因考試人員較多請盡快報名獲取最近考試時間,報名費用請聯系在線老師,甲骨文官方認證,報名從速!
我要咨詢
PostgreSQL從小白到專家,是從入門逐漸能力提升的一個系列教程,內容包括對PG基礎的認知、包括安裝使用、包括角色權限、包括維護管理、、等內容,希望對熱愛PG、學習PG的同學們有幫助,歡迎持續關注CUUG PG技術大講堂。
第43講:流復制原理
PostgreSQL第43講:1月27日(周六)19:30,釘釘群(35822460)& 視頻號(數據庫老陳)直播
內容1:流式復制的啟動方式
內容2:如何在主服務器和備用服務器之間傳輸數據
內容3:主服務器如何管理多個備用服務器
內容4:主服務器如何檢測備用服務器的故障
流復制啟動流程
開始流復制
1、主庫啟動walsender進程
2、備庫啟動startup與walreceiver進程
3、發出連接請求
4、握手成功
5、追趕沒有同步的數據
6、開始正常流復制

如何開始流復制
開始流復制
walsender進程保持如下可能狀態:
start-up –從啟動walsender到握手結束。
catch-up – 在追趕階段。
streaming –流媒體復制正在工作。
backup –為備份工具(如pg_basebackup utility)發送整個數據庫集群的文件時。 pg_stat_replication視圖顯示所有正在運行的walsender的狀態。示例如下:
testdb=# SELECT application_name,state FROM pg_stat_replication;
application_name | state
------------------+-----------
standby1 | streaming
standby2 | streaming
pg_basebackup | backup
預防歸檔日志缺失
預防歸檔日志缺失
如果備用服務器在長時間處于停止狀態后重新啟動,會發生什么情況?
在9.3或更早版本中,如果備用服務器所需的主服務器的WAL段已被回收,則備用服務器無法趕上主服務器。對于這個問題沒有可靠的解決方案,只能對配置參數wal_keep_segments設置一個較大的值,以減少發生這種情況的可能性。這是權宜之計。
在9.4版或更高版本中,可以使用復制插槽來防止此問題。復制槽是一種擴展WAL數據發送靈活性的功能,主要用于邏輯復制,這也為解決這個問題提供了解決方案-包含pg_xlog(或pg_WAL,如果版本10或更高版本)下未發送數據的WAL段文件可以通過暫停回收過程而保留在復制槽中。
如何進行流式復制
如何進行流復制
流復制同步有兩個方面:日志傳送和數據庫同步
日志傳送是其中主要的同步方式,因為流復制是基于它的——主服務器在寫入WAL數據時會將WAL數據發送到連接的備用服務器。
數據塊傳輸是同步復制時需要用到的另外一種方式—主服務器與每個多個備用服務器通信以同步其數據庫群集。
備庫可配置只讀訪問/不可訪問
假設備用服務器處于同步復制模式,hot standby配置為只讀訪問,配置如下:
synchronous_standby_names = 'standby1'
hot_standby = on
wal_level = archive
主備如何進行通訊
1、主庫寫WAL信息到WAL段文件。
2、主庫進程將WAL數據發送給備庫。
3、主庫繼續等待備庫的ACK響應。
4、備庫的將接收到的WAL數據寫入備庫的WAL緩沖區,并將ACK響應返回給主庫。
5、備庫將WAL數據寫到WAL段,向主庫返回另一個ACK響應。
6、備庫重放已寫入WAL段的WAL數據,向主庫返回另一個ACK響應
7、主庫在收到最后ACK響應時釋放鎖,然后提交完成。

備庫ACK響應
每個ACK響應通知主服務器備用服務器的內部信息。它包含以下四項:
已寫入wal緩存的最新WAL數據的LSN位置。
已刷新最新WAL數據的LSN位置。
啟動過程重放最新WAL數據的LSN位置。
發送此響應的時間戳。查看備庫寫入、刷新、應用wal日志的狀態
testdb=# SELECT application_name AS host, write_lsn AS write_LSN, flush_lsn AS flush_LSN, replay_lsn AS replay_LSN FROM pg_stat_replication;??
host | write_lsn | flush_lsn | replay_lsn
----------+-----------+-----------+------------
standby1 | 0/5000280 | 0/5000280 | 0/5000280
standby2 | 0/5000280 | 0/5000280 | 0/5000280
(2 rows)
心跳的間隔設置為參數wal_receiver_status_interval,默認為10秒。
復制故障排除
如何排除故障
同步備用服務器發生故障并且不再能夠返回ACK響應,主服務器仍將繼續永遠等待響應。因此,無法提交正在運行的事務,也無法啟動后續查詢處理。
流式復制不支持通過超時自動還原到異步模式(降級)的功能。
兩種解決辦法:
使用多個備用服務器來提高系統可用性
通過手動執行從同步模式切換到異步模式
(1) 將參數synchronous_standby_names設置為空字符串。
(2) 使用reload選項執行pg_ctl命令。
postgres> pg_ctl -D $PGDATA reload
上述過程不影響連接的客戶端。主服務器繼續事務處理,同時保留客戶端和相應后端進程之間的所有會話。
多備庫優先級狀態
多備庫優先級狀態
通過發出以下查詢,可以顯示備用服務器的優先級和狀態:
testdb=# SELECT application_name AS host, sync_priority, sync_state FROM pg_stat_replication;
host | sync_priority | sync_state
----------+---------------+------------
standby1 | 1 | sync
standby2 | 2 | potential
Sync是所有工作備用服務器(異步服務器除外)中優先級最高的同步備用服務器的狀態。
Potential是所有工作備用服務器(異步服務器除外)中優先級第二或更低的備用同步備用服務器的狀態。如果處于同步(sync狀態)的備庫失敗,它將替換為潛在待機中優先級最高的待機。
Async是異步備用服務器的狀態,此狀態是固定的。主服務器以與潛在備用服務器相同的方式處理異步備用服務器,只是它們的同步狀態永遠不是“sync”或“potential”。
管理多備庫
主庫與多備庫通訊方式

備庫優先級轉換

管理多備庫
備庫故障檢測
備庫進程故障檢測
當檢測到walsender和walreceiver之間的連接斷開時,主服務器立即確定備用服務器或walreceiver進程有故障。當底層網絡函數由于未能寫入或讀取walreceiver的socket接口而返回錯誤時,主函數也會立即確定其故障。
備庫硬件和網絡的故障檢測
如果walreceiver在為參數wal_sender_timeout(默認60秒)設置的時間內未返回任何內容,則主服務器將確定備用服務器存在故障。與上述故障相反,即使備用服務器無法再通過某些故障(例如,備用服務器的硬件故障、網絡故障等)發送任何響應,也需要一定時間(最長為wal_sender_timeout 秒)來確認主服務器上的備用服務器已死亡。(在確定故障之前的這段時間主服務器停止所有事務處理。)
CUUG PostgreSQL技術大講堂系列公開課第43講-流復制原理,往期視頻及文檔,請聯系CUUG。