内容簡要:
一、PostgreSQL高可用
二、PostgreSQL流複制
三、PostgreSQL邏輯複制
四、PostgreSQL高可用叢集
(一)PostgreSQL高可用的種類
l 常用的高可用架構及基本原理包括:
1)共享存儲;
2)流複制;
3)邏輯複制;
1. 共享存儲:
共享存儲是所用的存儲空間相同,但執行個體運作放在不同的節點上。
示意圖如下:

當在正常工作狀态,主節點在計算機上啟動,但是計算機裡檔案系統是接在SAN存儲上,SAN存儲同時也可以連接配接到備用節點,正常情況下主節點對共享存儲進行讀寫,對外提供業務和服務。
如上圖所示,當主節點故障時,會由備用節點接管資料庫,重新啟動執行個體做復原。這種架構底層用到專門的存儲叫SAN,它的好處是資料放在共享存儲上,當主節點壞掉,從節點啟動後會沿着主節點壞掉的時間點進行復原,復原到最後一次切換,經過Commit和Rollback,最後把資料庫打開對外提供服務,不會丢資料。
這對資料可靠性要求較高的行業,是比較好的方案。
2.流複制
在Oracle裡面,可以用對等的DataGate概念對應PostgreSQL的流複制。根據資料流,每一個資料流Commit的時候會複制下去。
流複制分為:同步流複制和異步流複制。
根據使用者不同的配置情況,在流複制裡面可以搭建很多節。主節點上面,對外正常提供讀寫服務,然後通過流複制,可以挂一個或者多個從節點。在從節點上面,可以根據業務場景的需要,對高可用的需要或者負載均衡的需要,搭建一個或者多個二級從節點,根據業務需求,第二級從節點上再往後可以搭建第三、第四、第五等多級從節點。
流複制特點總結:
• 主節點可以有多個從節點;
• 從節點上還可以挂載從節點;
• 從節點個數沒有明确限制,層級無限制;
• 主從間可以同步複制、可以一步複制,也可以同步一步混合複制。
3.邏輯複制
邏輯複制是資料庫内部資料塊的具體操作,比如Insert、Delete操作解析出來,經過釋出節點Sender程序向外釋出之後,然後訂閱節點對訂閱 Publisher定義的指定名字進行搜尋表的操作。
邏輯複制特點總結:
• 所有節點都是對等關系,都可讀寫;
• 所有節點可以是釋出節點,訂閱節點,也可以同時是釋出節點和訂閱節點。
邏輯複制和流複制之間的差别是:
• 流複制裡隻有一個主節點,可以挂很多從節點。邏輯複制裡所有的節點都是對等的主節點,都可以提供對外讀寫操作。
• 邏輯複制實際是從邏輯上把 SQL解析出來,到其他訂閱節點進行重放,相當于SQL的重新回放。流複制釋出的資料是更改的資料塊。
PostgreSQL資料庫流複制基本原理
如上圖所示,從寫程式流程來看基本原理,首先啟動Postmaster程序,系統正常運作,如果用戶端(WalReciver)進行流複制,啟動之後用戶端會連到Master,Master收到流複制信号會Fork一個指定層,指定層啟動WalSender,後面是相應的流程,根據系統ID或使用者網段在相應時間内完成。
計算要從什麼時間點取什麼資料呢?
系統在有SendTimeLineHistory的情況下會選擇優先使用,否則會去做一些其他操作。通過CreateReplicationSlot開始找複制的時間點拷貝資料,SendPhysicak收到私人資訊後會進行寫操作,整個流程形成一個大循環。
資料庫的Commit操作之後,Execute執行器将要改的髒資料寫到WAL中,通過Sender發送到從資料庫,從資料庫這端對應的Receiver寫到WAL日志裡面,WAL再到資料庫檔案Date File Heaps,寫到資料庫之後,外面的查詢執行器就可以進行取資料,以上就是流複制的大緻流程。
上方為流複制環境搭建實作過程,用 pg_basebackup指令搭建,用 help關鍵的參數,這裡“-d”是拷貝過來的資料庫要放在哪個目錄,“-f”是用什麼樣子的格式拷過來,“p|t”t是純文字,p是裸資料,“-r”是以什麼樣子的速率來拷,可以限制它的速度等等。
下面舉一個簡單的例子:
首先定義到“data/appdb”目錄,用basebackup指令,從主節點“192.168.56.3”通過Replicator使用者,把“d”指定到這裡,“-R -Fp -Xs –P”,“-R”指令會建立一個從節點,同時自動建立Replicator檔案。
如果是設定同步複制,通過synchronous_standby_names控制同步複制。例如部署一套系統在兩個資料中心裡面,這兩個資料中心通過FIRST 2 (application1,application2,application3)的方式Commit成功了,認為整個系統成功。
l Synchronous_satandby_names=FIRST 2(application1, application2, application3)
Application1與Application2在同一個資料中心,是以主節點Commit的時候要保證Application1與Application2兩個節點同時成功。
FIRST 2是定義三個Application,定義前面兩個成功則認為送出成功。用特性限制伺服器可以限制整個架構,例如同城用一個Commit或者異地用一個Commit,可根據實際情況進行定義。
l Synchronous_satandby_names=ANY 2(application1, application2, application3)
一個資料庫三個 Slave,隻需要Application1/2/3其中任意兩個Commit成功即可。
l Synchronous_commit=off
同步複制有幾個點來控制具體行為,這些行為會決定Commit本身的性能與可靠性等。如下圖所示:
首先在主節點上面Commit,Executer直接寫記憶體,相當于從WAL buffer裡去寫WAL檔案,這個過程隻确認WAL buffer裡面的東西是否寫到檔案系統中,這個時候相當于關閉本地寫WAL檔案的過程,具有一定風險,但是Commit傳回會非常快。
l Synchronous_commit=local
synchronous_commit=local表示Commit的時候将資料寫到本地的WAL檔案裡,資料庫是寫到本地送出。雖然是同步,但Local的可靠性比 Off要高一點,能保證主節點上面資料寫入到日志。
l Synchronous_commit=on(default)
還有一個選項synchronous_commit=on(default),On表示Commit完成。Commit之後寫到WAL檔案中,然後通過 WAL Sender發送出去,從端接收資料,同時将資料寫到從端的WAL filed中,這個是預設的級别,相當于本地的WAL與從端的WAL裡都有這個資料,資料就是安全的。
l Synchronous_commit=remote_write
Sender發送資料,Reserve收到後向檔案系統中寫資料,把資料送出給檔案系統的緩存,不會把資料從緩存中刷到磁盤内。相當于對端那個伺服器,這個傳回非常快,因為當資料Flash到WAL檔案時它已經傳回,但隻能保證本地這一份資料的可靠性,無法保證遠端那一份資料的可靠性,有可能會導緻資料丢失。
如果遇到一些極端情況,例如Commit恰好在中間某處,Reserve往下寫但還沒有寫到WAL檔案之前,如果這個時候阻斷斷電,從端沒有把資料切換,将資料庫切換成組,就可能會存在一定的問題。
l synchronous_commit = remote_apply
資料寫到WAL檔案中,從端資料庫把資料Apply到遠端的資料庫了,此時兩端資料庫裡面的内容完全一緻。如下圖所示:
Remote_play是複制性能最低的一種,一旦資料Remote_play到遠端的資料庫之後,主端有什麼資料,從端就一定能看見什麼樣的資料。
但是在Synchronous_commit=on(default)預設的情況下,資料則不一定相同。因為主端寫的壓力很大,隻會将從端寫到WAL中。由于是先改的髒資料再去改資料,是以主端可以查,但在從端因為做 Replay的時候速度是串行的,Replay的性能不一定能跟上,是以這個時候到從端去查資料不一定能夠查到,但這并不意味着資料丢失,而是因為資料仍在WAL中,還沒恢複到資料庫裡。
1.邏輯複制的工作原理
邏輯複制有個概念是釋出者和訂閱者,主端如果要通過邏輯複制,首先要進行定義,配置檔案裡面有一個日志級别,要把它設定為Logical之後的話就可以去定義Publisher,傳輸通道是用Sender or Reserve機制。
2.邏輯複制搭建
首先在釋出端確定Level(此處指Logical),確定邏輯複制可以正常進行。通過PG_hba設定使用者所需要的權限,設定完成之後可以到資料庫中去定義Publication。例如定Publication的名字為“insert _only”,然後FOR TABLE叫“mydata”,table給它定義一個權限WITH (publish = 'insert');,此時,這張表隻會去做釋出Insert、Update、Delete這樣的操作,不會往外發送,使用者可以通過Publish關鍵字裡面定義多個行為。
當指令執行完之後,Population也完成,接着設定訂閱端,通過CREATE SUBSCRIPTION mysub,同樣要跟連接配接串定義,例如是主機、端口、使用者、資料庫等,有了連接配接串之後,Publication用定義對應的名字,這樣在主端做什麼事情,從端馬上可以得到回報。
四、PostgreSQL ECOX高可用叢集
ECOX是一個專門為PostgreSQL流複制設計的高可用叢集。
如上圖所示,ECOX有一個仲裁叢集,它避免單點故障導緻誤判。一個仲裁叢集可以管N個PG叢集,在PG叢集内部的主從是自動切換的。
上圖為ECOX的基本原理例子,有0、1、2三個節點,可以看到節點的IP與端口是否線上,Master、Commaster與Last Master的詳情。
這個系統目前支援PostgreSQL,Hunghu DB以及KingBase新版本。
我們也将ECOX做到自己的資料雲平台“鴻鹄彩雲”中,支援PostgreSQL、Greenplum,給業務帶來了很大的幫助。