集群故障后如何恢復原主機
pg的高可用架構中,主庫掛掉后,備庫會自動升級為主庫繼續提供服務,對於原來的主庫通常有兩種處理方式
- 刪掉,重搭新備庫。
- 降級為備庫,繼續服務。
很顯然,相比來說第一種不是個很好的方案,而且當數據量比較大時,重搭備庫的時間成本太高。
但是因為老的主庫掛掉的原因多種多樣,甚至有可能是高可用系統的誤判,而老主庫也有可能是在掛掉之后又重新作為主庫啟動起來,這個時候降級並重搭流復制關系的操作就有可能失敗(新的備庫比新主庫數據更超前)。
為了解決這種情況,PostgreSQL 引入了pg_rewind工具。
pg_rewind
pg_rewind 工具主要實現了從源集群到目的集群的文件級別數據同步。但是和rsync的區別是,pg_rewind 不需要去讀那些未變化的文件塊,當數據量比較大而變化較小的時候,pg_rewind會更快。
先看下官方介紹:
pg_rewind是一個工具,用於在群集的時間線發生分歧之后,將PostgreSQL群集與同一群集的另一個副本進行同步。典型的方案是在故障轉移后將舊的主服務器恢復聯機,作為新主服務器之后的備用服務器。
優勢是啥?
pg_rewind 工具主要實現了從源集群到目的集群的文件級別數據同步,pg_rewind 不需要去讀那些未變化的文件塊,當數據量比較大而變化較小的時候,pg_rewind會更快。
pg_rewind為了能夠支持文件級別的數據同步,postgresql.conf必須配置如下參數
wal_log_hints=on
full_page_writes=on
具體實現
為了在PostgreSQL 中實現文件級別同步數據的功能,pg_rewind 主要進行了如下的處理步驟:
-
在目的集群中找到源集群和目的集群的分叉點之前的最近一次checkpoint 點。這樣相當於找到了在兩個副本數據產生不同前的最后一個一致性位點。目的集群在這個位點之后所有的表數據變化都記錄在這個位點之后的WAL 日志中。
-
pg_rewind 會將目的集群這些變化的數據頁從源集群復制過來。這里會有2種方式:
-
使用文件系統方式拷貝
-
使用 libpq 建立連接的方式拷貝
總結來講:pg_rewind 可以快速找到兩個集群數據開始分叉的點,然后找到目的集群從該點之后的數據變化,通過拷貝源集群的對應數據頁,再通過應用源集群的WAL 日志達到數據一致。