從0到1,PostgreSQL復(fù)制的不同策略詳解
作為一個(gè)開發(fā)者,我們知道一個(gè)網(wǎng)站如果數(shù)據(jù)丟失和停機(jī),即使是很少、很短暫,也可能是災(zāi)難性的,并且降低生產(chǎn)力、可訪問性和產(chǎn)品信心。
為保護(hù)站點(diǎn)的完整性,建立防范停機(jī)或數(shù)據(jù)丟失的措施至關(guān)重要。
數(shù)據(jù)復(fù)制是一種自動(dòng)備份過程,數(shù)據(jù)會(huì)從其主數(shù)據(jù)庫復(fù)制到另一個(gè)遠(yuǎn)程位置以進(jìn)行妥善保管。對于運(yùn)行數(shù)據(jù)庫服務(wù)器的任何站點(diǎn)或應(yīng)用程序來說,它都是一項(xiàng)不可或缺的技術(shù)。我們還可以利用復(fù)制的數(shù)據(jù)庫來處理只讀 SQL,從而允許在系統(tǒng)內(nèi)運(yùn)行更多進(jìn)程。
在兩個(gè)數(shù)據(jù)庫之間設(shè)置復(fù)制是很有必要了,它提供了針對意外事故的容錯(cuò)能力,這也是在災(zāi)難期間實(shí)現(xiàn)高可用性的最佳策略。
在本文中,我們將深入探討 PostgreSQL 復(fù)制的不同策略。
什么是 PostgreSQL 復(fù)制?
PostgreSQL 復(fù)制是將數(shù)據(jù)從PostgreSQL 數(shù)據(jù)庫服務(wù)器復(fù)制到另一臺(tái)服務(wù)器的過程。源數(shù)據(jù)庫服務(wù)器也稱為“主”服務(wù)器,而接收復(fù)制數(shù)據(jù)的數(shù)據(jù)庫服務(wù)器稱為“副本”服務(wù)器。
PostgreSQL 數(shù)據(jù)庫遵循簡單的復(fù)制模型,其中所有寫入都轉(zhuǎn)到主節(jié)點(diǎn)。然后主節(jié)點(diǎn)可以應(yīng)用這些更改并將它們廣播到輔助節(jié)點(diǎn)。
什么是自動(dòng)故障轉(zhuǎn)移?
故障轉(zhuǎn)移是一種在主服務(wù)器因一些原因失效時(shí)恢復(fù)數(shù)據(jù)的方法。不過只要你配置了 PostreSQL 來進(jìn)行物理流復(fù)制,就不會(huì)因主服務(wù)器故障而停機(jī)。
請注意,故障轉(zhuǎn)移過程可能需要一些時(shí)間來設(shè)置和啟動(dòng)。PostgreSQL 中沒有用于監(jiān)視和確定服務(wù)器故障范圍的內(nèi)置工具,因此需要我們自行發(fā)揮。
不過幸運(yùn)的是,我們需要依賴 PostgreSQL 進(jìn)行故障轉(zhuǎn)移。有專用工具來進(jìn)行自動(dòng)故障轉(zhuǎn)移和自動(dòng)切換到備用數(shù)據(jù)庫,從而減少數(shù)據(jù)庫停機(jī)時(shí)間。
通過設(shè)置故障轉(zhuǎn)移復(fù)制,即使主服務(wù)器崩潰時(shí),也可以通過備用服務(wù)器切換來保證高可用性。
使用 PostgreSQL 復(fù)制的好處
以下是利用 PostgreSQL 復(fù)制的一些主要優(yōu)勢:
- 數(shù)據(jù)遷移:可以通過更改數(shù)據(jù)庫服務(wù)器硬件或通過系統(tǒng)部署來使用 PostgreSQL 復(fù)制進(jìn)行數(shù)據(jù)遷移。
- 容錯(cuò)性:如果主服務(wù)器發(fā)生故障,備用服務(wù)器可以充當(dāng)服務(wù)器,因?yàn)橹鞣?wù)器和備用服務(wù)器包含的數(shù)據(jù)是相同的。
- 聯(lián)機(jī)事務(wù)處理 (OLTP) 性能:可以通過移除報(bào)告查詢負(fù)載來改進(jìn) OLTP 系統(tǒng)的事務(wù)處理時(shí)間和查詢時(shí)間。事務(wù)處理時(shí)間是在事務(wù)完成之前執(zhí)行給定查詢所花費(fèi)的持續(xù)時(shí)間。
- 并行系統(tǒng)測試:在升級新系統(tǒng)時(shí),需要確保系統(tǒng)能夠很好地處理現(xiàn)有數(shù)據(jù),因此需要在部署前使用生產(chǎn)數(shù)據(jù)庫副本進(jìn)行測試。
PostgreSQL 復(fù)制的工作原理
通常,一般的機(jī)構(gòu)中只有一種方法可以設(shè)置備份和復(fù)制。然而,PostgreSQL 可以有三種,分別如下:
- 流復(fù)制:將數(shù)據(jù)從主節(jié)點(diǎn)復(fù)制到從節(jié)點(diǎn),然后將數(shù)據(jù)復(fù)制到 S3 等文件服務(wù)器進(jìn)行備份存儲(chǔ)。
- 卷級復(fù)制:在存儲(chǔ)層復(fù)制數(shù)據(jù),從主節(jié)點(diǎn)開始復(fù)制到從節(jié)點(diǎn),然后將數(shù)據(jù)復(fù)制到 S3 等進(jìn)行備份存儲(chǔ)。
- 增量備份:從主節(jié)點(diǎn)復(fù)制數(shù)據(jù),同時(shí)從 S3 等文件服務(wù)器存儲(chǔ)構(gòu)建新的輔助節(jié)點(diǎn),允許直接從主節(jié)點(diǎn)流式傳輸。
方法一:流復(fù)制
PostgreSQL 流復(fù)制也稱為 WAL 復(fù)制,可以在服務(wù)器上安裝 PostgreSQL 后無縫設(shè)置。這種復(fù)制方法基于將 WAL 文件從主數(shù)據(jù)庫復(fù)制到目標(biāo)數(shù)據(jù)庫來完成的。
通過使用主從配置來實(shí)現(xiàn) PostgreSQL 流式復(fù)制。主服務(wù)器是處理主數(shù)據(jù)庫及其所有操作的主要實(shí)例。輔助服務(wù)器充當(dāng)補(bǔ)充實(shí)例并執(zhí)行復(fù)制對主數(shù)據(jù)庫所做的所有更改,并在此過程中生成相同的副本。主服務(wù)器是讀/寫服務(wù)器,而輔助服務(wù)器只是只讀的。
這種方法需要同時(shí)配置主節(jié)點(diǎn)和備節(jié)點(diǎn)。以下部分將闡明配置所涉及的步驟。
配置主節(jié)點(diǎn)
通過執(zhí)行以下步驟來配置主節(jié)點(diǎn):
第一步:初始化數(shù)據(jù)庫
我們可以利用 initdb 程序命令來初始化數(shù)據(jù)庫。接下來,使用命令創(chuàng)建具有復(fù)制權(quán)限的新用戶:
用戶在查詢時(shí),必須提供密碼和用戶名。REPLICATION 關(guān)鍵字用于為用戶提供所需的權(quán)限。示例如下:
第二步:配置流屬性
接下來,使用 PostgreSQL 配置文件 ( postgresql.conf )配置流媒體屬性,如下:
配置解析:
- wal_level:此參數(shù)用于啟用 PostgreSQL 流復(fù)制,值包括minimal、replica或logical。
- wal_log_hints:控制在 WAL 日志文件中是否包含有關(guān)寫入哪個(gè)數(shù)據(jù)文件的提示信息。當(dāng)該參數(shù)設(shè)置為 ON 時(shí),WAL 日志中的每個(gè)記錄將包含有關(guān)數(shù)據(jù)文件的信息,以便在進(jìn)行數(shù)據(jù)庫恢復(fù)時(shí)可以更快地定位需要恢復(fù)的數(shù)據(jù)。當(dāng)備用服務(wù)器與主服務(wù)器不同步時(shí),此參數(shù)是pg_rewind 功能所必需的。
- max_wal_senders:指定可以與備用服務(wù)器建立的最大并發(fā)連接數(shù)。
- max_wal_size:指定可保留在日志文件中的 WAL 文件的大小。
- hot_standby:當(dāng)它設(shè)置為 ON 時(shí),可以利用此參數(shù)與輔助設(shè)備建立讀取連接。
第三步:創(chuàng)建新條目
修改 postgresql.conf 文件中的參數(shù)后, pg_hba.conf 文件中的新 replication 條目可以允許服務(wù)器相互建立連接以進(jìn)行復(fù)制。
可以在 PostgreSQL 的數(shù)據(jù)目錄中找到這個(gè)文件,配置條目如下:
執(zhí)行以下代碼片段后,主服務(wù)器就允許調(diào)用的用戶(rep_user)通過使用指定的 IP 進(jìn)行連接并充當(dāng)備用服務(wù)器進(jìn)行復(fù)制。示例:
配置備節(jié)點(diǎn)
步驟 1:備份主節(jié)點(diǎn)
要配置備用節(jié)點(diǎn),需要用 pg_basebackup 程序生成主節(jié)點(diǎn)的備份,這將作為備用節(jié)點(diǎn)的起點(diǎn)。命令如下:
上述語法中使用的參數(shù)如下:
- -h:主要主機(jī)。
- -D:表示當(dāng)前正在處理的目錄。
- -C:設(shè)置檢查點(diǎn)。
- -X:此參數(shù)可用于包含必要的事務(wù)日志文件。
- -W:設(shè)置用戶在連接到數(shù)據(jù)庫之前提示用戶輸入密碼。
步驟 2:設(shè)置復(fù)制節(jié)點(diǎn)配置文件
接下來,我們需要檢查復(fù)制配置文件是否存在。如果沒有,生成復(fù)制配置文件,名稱為:recovery.conf。
在 PostgreSQL 安裝的數(shù)據(jù)目錄中創(chuàng)建此文件,也可以用 pg_basebackup 程序-R 選項(xiàng)自動(dòng)生成。
recovery.conf文件應(yīng)包含以下命令:
上述命令中使用的參數(shù)如下:
- primary_conninfo:通過利用連接字符串在主服務(wù)器和輔助服務(wù)器之間建立連接。
- standby_mode:通過啟用"pg_standby_mode"模式,備用服務(wù)器可以在主服務(wù)器失效時(shí),接管主服務(wù)器的職責(zé),確保數(shù)據(jù)的可用性和持久性。
- recovery_target_timeline:設(shè)置恢復(fù)時(shí)間線。在數(shù)據(jù)庫恢復(fù)時(shí),需要指定恢復(fù)的時(shí)間線,以便將備份數(shù)據(jù)正確地還原到指定的時(shí)間點(diǎn)。
要建立連接,需要提供用戶名、IP 地址和密碼作為 primary_conninfo 參數(shù)的值。示例:
步驟 3:重新啟動(dòng)備份服務(wù)器
最后,重新啟動(dòng)備份服務(wù)器以完成配置過程。
然而,流復(fù)制會(huì)帶來一些挑戰(zhàn),例如:
- 各種 PostgreSQL 客戶端(用不同的編程語言編寫)與單個(gè)端點(diǎn)進(jìn)行交互。當(dāng)主節(jié)點(diǎn)出現(xiàn)故障時(shí),這些客戶端將繼續(xù)重試相同的 DNS 或 IP 名稱。這使得故障轉(zhuǎn)移對應(yīng)用程序可見。
- PostgreSQL 復(fù)制沒有內(nèi)置的故障轉(zhuǎn)移和監(jiān)控功能。當(dāng)主節(jié)點(diǎn)發(fā)生故障時(shí),我們需要將一個(gè)備份節(jié)點(diǎn)提升為新的主節(jié)點(diǎn)。這種提升需要讓用戶無感知,且不會(huì)出現(xiàn)數(shù)據(jù)不一致問題。
- PostgreSQL 需要復(fù)制主節(jié)點(diǎn)的整個(gè)狀態(tài)。當(dāng)你需要開發(fā)一個(gè)新的備份節(jié)點(diǎn)時(shí),需要從主節(jié)點(diǎn)重放狀態(tài)變化的整個(gè)歷史,這會(huì)導(dǎo)致很大的資源消耗,并且使得刪除頭部節(jié)點(diǎn)和創(chuàng)建新節(jié)點(diǎn)的成本很高。
方法二:RBD(塊設(shè)備復(fù)制)
?RBD 方法依賴于磁盤鏡像(也稱為卷復(fù)制)。在這種方法中,更改被寫入一個(gè)持久卷,該卷被同步鏡像到另一個(gè)卷。
RBD 是一個(gè)基于Ceph分布式存儲(chǔ)系統(tǒng)的塊設(shè)備復(fù)制方案,用于在PostgreSQL數(shù)據(jù)庫中實(shí)現(xiàn)高可用性和容錯(cuò)性。它通過將主服務(wù)器上的數(shù)據(jù)塊實(shí)時(shí)復(fù)制?到備用服務(wù)器上,以確保在主服務(wù)器出現(xiàn)故障或宕機(jī)時(shí),備用服務(wù)器可以立即接管其職責(zé)。
RBD是一個(gè)基于網(wǎng)絡(luò)塊設(shè)備的復(fù)制方案,它可以在多個(gè)Ceph節(jié)點(diǎn)之間實(shí)現(xiàn)數(shù)據(jù)復(fù)制,并通過Ceph的故障轉(zhuǎn)移機(jī)制來保證數(shù)據(jù)的可用性和一致性。在RBD中,主服務(wù)器和備用服務(wù)器之間通過Ceph集群的網(wǎng)絡(luò)通信,實(shí)現(xiàn)數(shù)據(jù)塊的實(shí)時(shí)復(fù)制和同步。
與其他流復(fù)制方案相比,RBD具有以下優(yōu)點(diǎn):
- 數(shù)據(jù)復(fù)制速度更快:RBD通過Ceph的對象存儲(chǔ)方式來管理數(shù)據(jù),可以實(shí)現(xiàn)高效的數(shù)據(jù)復(fù)制和同步,比傳統(tǒng)的流復(fù)制方案速度更快。
- 數(shù)據(jù)安全性更高:RBD可以使用Ceph的數(shù)據(jù)加密和數(shù)據(jù)壓縮功能,提高數(shù)據(jù)的安全性和傳輸效率。
- 可擴(kuò)展性更好:RBD可以根據(jù)需要對Ceph存儲(chǔ)集群進(jìn)行擴(kuò)展,以滿足不同的存儲(chǔ)需求。
- 系統(tǒng)穩(wěn)定性更高:由于RBD是基于Ceph的分布式存儲(chǔ)系統(tǒng)實(shí)現(xiàn)的,因此具有更好的容錯(cuò)性和可靠性,可以確保數(shù)據(jù)的可用性和一致性。
方法三:WAL
WAL 由段文件組成(默認(rèn)為 16 MB)。每個(gè)段都有一個(gè)或多個(gè)記錄。日志序列記錄 (LSN) 是指向 WAL 中記錄的指針,用于記錄在日志文件中保存的位置(position/location)。
備份服務(wù)器利用 WAL 段(在 PostgreSQL 術(shù)語中也稱為 XLOGS)從其主服務(wù)器不斷復(fù)制更改。你可以通過在DBMS中使用預(yù)寫日志(write-ahead logging)來為數(shù)據(jù)提供持久性和原子性,具體做法是在將字節(jié)數(shù)組數(shù)據(jù)塊(每個(gè)塊都帶有唯一的LSN)應(yīng)用到數(shù)據(jù)庫之前,將它們序列化并寫入穩(wěn)定的存儲(chǔ)介質(zhì)
將變更應(yīng)用到數(shù)據(jù)庫可能會(huì)引起各種文件系統(tǒng)操作。一個(gè)相關(guān)的問題是,在文件系統(tǒng)更新過程中,如果服務(wù)器由于停電而發(fā)生故障,數(shù)據(jù)庫如何確保原子性。具體做法是當(dāng)數(shù)據(jù)庫啟動(dòng)時(shí),它會(huì)開始一個(gè)啟動(dòng)或重放過程,該過程可以讀取可用的WAL段,并將它們與存儲(chǔ)在每個(gè)數(shù)據(jù)頁上的LSN進(jìn)行比較(每個(gè)數(shù)據(jù)頁都標(biāo)記有影響該頁的最新WAL記錄的LSN)。
基于日志發(fā)送的復(fù)制(塊級)
流復(fù)制改進(jìn)了日志發(fā)送的過程。與等待WAL切換不同,記錄在創(chuàng)建時(shí)就被發(fā)送,從而減少了復(fù)制延遲。
流復(fù)制也勝過日志發(fā)送,因?yàn)閭浞莘?wù)器通過復(fù)制協(xié)議在網(wǎng)絡(luò)上與主服務(wù)器建立連接。主服務(wù)器可以直接通過這個(gè)連接發(fā)送WAL記錄,而不必依賴于用戶提供的腳本。
基于日志發(fā)送的復(fù)制(文件級)
日志發(fā)送是將日志文件復(fù)制到另一臺(tái)PostgreSQL服務(wù)器,通過重放WAL文件生成另一臺(tái)備用服務(wù)器。且此服務(wù)器被配置為在恢復(fù)模式下工作,目的是為了在監(jiān)聽新的 WAL 文件,并進(jìn)行應(yīng)用。
備份服務(wù)器將成為主 PostgreSQL 服務(wù)器的熱備份。它還可以配置為只讀副本,可以提供只讀查詢。
WAL 歸檔
在創(chuàng)建 WAL 文件時(shí)將其復(fù)制到除pg_wal子目錄以外的任何位置以將其歸檔稱為 WAL 歸檔。每次創(chuàng)建 WAL 文件時(shí),PostgreSQL 都會(huì)調(diào)用用戶提供的腳本進(jìn)行歸檔。
該腳本可以利用該scp命令將文件復(fù)制到一個(gè)或多個(gè)位置,例如 NFS 。存檔后,可以利用 WAL 段文件恢復(fù)數(shù)據(jù)庫到任何給定時(shí)間點(diǎn)。
其他基于日志的配置如下:
- 同步復(fù)制:在提交每個(gè)同步復(fù)制事務(wù)之前,主服務(wù)器會(huì)等待備用服務(wù)器以確認(rèn)它們已獲取數(shù)據(jù)。這種配置的好處是不會(huì)因?yàn)椴⑿袑懭脒M(jìn)程而導(dǎo)致任何沖突。
- 同步多主復(fù)制:這種情況下,每個(gè)服務(wù)器都可以接受寫入請求,并且在每個(gè)事務(wù)提交之前,修改后的數(shù)據(jù)從原始服務(wù)器傳輸?shù)矫總€(gè)其他服務(wù)器。它利用 2PC 協(xié)議并遵守全有或全無規(guī)則。
WAL 流協(xié)議詳細(xì)信息
WAL接收器的進(jìn)程運(yùn)行在備用服務(wù)器上,利用recovery.conf中提供的primary_conninfo參數(shù)中的連接詳細(xì)信息,通過TCP/IP連接到主服務(wù)器。
開始流式復(fù)制時(shí),前端可以在啟動(dòng)消息中發(fā)送復(fù)制參數(shù)。值為true、yes、1或ON的布爾值讓后端知道它需要進(jìn)入物理復(fù)制walsender模式。
WAL發(fā)送器是在主服務(wù)器上運(yùn)行的另一個(gè)進(jìn)程,負(fù)責(zé)在生成WAL記錄時(shí)將其發(fā)送到備用服務(wù)器。WAL接收器將WAL記錄保存在WAL中,就像本地的客戶端連接一樣。
一旦WAL記錄到達(dá)WAL段文件,備用服務(wù)器就不斷地重放WAL,以使主服務(wù)器和備用服務(wù)器保持最新同步狀態(tài)。
PostgreSQL 復(fù)制的要素
接下來我們將更深入地了解 PostgreSQL 復(fù)制的常用模型(單主復(fù)制和多主復(fù)制)、類型(物理復(fù)制和邏輯復(fù)制)以及模式(同步和異步)。
PostgreSQL 數(shù)據(jù)庫復(fù)制模型
可擴(kuò)展性是指向現(xiàn)有節(jié)點(diǎn)添加更多資源/硬件,以增強(qiáng)數(shù)據(jù)庫存儲(chǔ)和處理更多數(shù)據(jù)的能力,可以進(jìn)行水平和垂直擴(kuò)展。PostgreSQL 復(fù)制是水平可伸縮性的一個(gè)例子,它比垂直可伸縮性更難實(shí)現(xiàn)。主要通過單主復(fù)制(SMR)和多主復(fù)制(MMR)來實(shí)現(xiàn)水平擴(kuò)展。
單主復(fù)制僅允許在單個(gè)節(jié)點(diǎn)上修改數(shù)據(jù),并將這些修改復(fù)制到一個(gè)或多個(gè)節(jié)點(diǎn)。副本數(shù)據(jù)庫中的復(fù)制表不允許接受任何更改,但來自主服務(wù)器的更改除外。
大多數(shù)時(shí)候,SMR 足以滿足應(yīng)用程序的需求,因?yàn)樗呐渲煤凸芾聿荒敲磸?fù)雜,而且不會(huì)發(fā)生沖突。單主復(fù)制也是單向的,因?yàn)閺?fù)制數(shù)據(jù)主要在一個(gè)方向上流動(dòng),從主數(shù)據(jù)庫到副本數(shù)據(jù)庫。
在某些情況下,單靠 SMR 可能不夠,你可能需要實(shí)施 MMR。MMR 允許多個(gè)節(jié)點(diǎn)充當(dāng)主節(jié)點(diǎn)。對多個(gè)指定主數(shù)據(jù)庫中表行的更改將復(fù)制到每個(gè)其他主數(shù)據(jù)庫中的對應(yīng)表。在這個(gè)模型中,經(jīng)常采用沖突解決方案來避免重復(fù)主鍵等問題。
使用 MMR 有幾個(gè)優(yōu)點(diǎn),即:
- 在主機(jī)故障的情況下,其他主機(jī)仍然可以提供更新和插入服務(wù)。
- 主節(jié)點(diǎn)分布在幾個(gè)不同的位置,因此所有主節(jié)點(diǎn)發(fā)生故障的可能性很小。
- 能夠使用主數(shù)據(jù)庫的廣域網(wǎng) (WAN),這些主數(shù)據(jù)庫在地理位置上可以靠近客戶端組,同時(shí)保持網(wǎng)絡(luò)中的數(shù)據(jù)一致性。
然而,實(shí)施 MMR 的缺點(diǎn)是復(fù)雜性和沖突難以解決。
一些機(jī)構(gòu)和應(yīng)用程序提供 MMR 解決方案,因?yàn)?PostgreSQL 本身并不支持。這些解決方案可能是開源的、免費(fèi)的或付費(fèi)的。如雙向復(fù)制 (BDR),它是異步的并且基于 PostgreSQL 邏輯解碼功能。
由于 BDR 應(yīng)用程序在其他節(jié)點(diǎn)上重放事務(wù),如果正在應(yīng)用的事務(wù)與在接收節(jié)點(diǎn)上提交的事務(wù)之間存在沖突,重放操作可能會(huì)失敗。
PostgreSQL 復(fù)制的類型
PostgreSQL 復(fù)制有兩種類型:邏輯復(fù)制和物理復(fù)制。
一個(gè)簡單的 initdb 邏輯操作,將會(huì)執(zhí)行為集群創(chuàng)建基準(zhǔn)目錄的物理操作。同樣,一個(gè)簡單的邏輯操作(CREATE DATABASE)將執(zhí)行為在基準(zhǔn)目錄中創(chuàng)建子目錄的物理操作。
物理復(fù)制通常處理文件和目錄。它不知道這些文件和目錄代表什么。物理復(fù)制方法用于在另一臺(tái)機(jī)器上維護(hù)單個(gè)集群的完整數(shù)據(jù)副本,并且在文件系統(tǒng)級別或磁盤級別進(jìn)行,并使用精確的塊地址。
邏輯復(fù)制是一種根據(jù)復(fù)制標(biāo)識(通常是主鍵)復(fù)制數(shù)據(jù)實(shí)體及其修改的方法。與物理復(fù)制不同,它處理數(shù)據(jù)庫、表和 DML 操作,并在數(shù)據(jù)庫集群級別完成。它使用發(fā)布和訂閱模型,一個(gè)訂閱者可以訂閱發(fā)布者節(jié)點(diǎn)上的一個(gè)或多個(gè)發(fā)布。
復(fù)制過程首先對發(fā)布者數(shù)據(jù)庫上的數(shù)據(jù)進(jìn)行快照,然后將其復(fù)制到訂閱者。訂閱者從他們訂閱的發(fā)布中提取數(shù)據(jù),并可能稍后重新發(fā)布數(shù)據(jù),以允許級聯(lián)復(fù)制或更復(fù)雜的配置。訂閱者以與發(fā)布者相同的順序應(yīng)用數(shù)據(jù),以便保證單個(gè)訂閱內(nèi)的發(fā)布的事務(wù)一致性,也稱為事務(wù)復(fù)制。
邏輯復(fù)制的典型場景如下:
- 將單個(gè)數(shù)據(jù)庫(或數(shù)據(jù)庫的子集)中的增量更改發(fā)送給訂閱者。
- 在多個(gè)數(shù)據(jù)庫之間共享數(shù)據(jù)庫的一個(gè)子集。
- 在單個(gè)更改到達(dá)訂閱者時(shí)觸發(fā)它們的觸發(fā)事件。
- 將多個(gè)數(shù)據(jù)庫合并為一個(gè)。
- 為不同的用戶組提供對復(fù)制數(shù)據(jù)的訪問。
訂閱者數(shù)據(jù)庫的行為方式與任何其他 PostgreSQL 實(shí)例相同,并且可以通過定義其發(fā)布來用作其他數(shù)據(jù)庫的發(fā)布者。
當(dāng)訂閱者被應(yīng)用程序配置成只讀時(shí),單個(gè)訂閱不會(huì)發(fā)生沖突。不過,如果應(yīng)用程序或其他訂閱者對同一組表進(jìn)行了寫入,則可能會(huì)出現(xiàn)沖突。
PostgreSQL 同時(shí)支持這兩種機(jī)制。邏輯復(fù)制允許對數(shù)據(jù)復(fù)制和安全性進(jìn)行細(xì)粒度控制。
復(fù)制模式
PostgreSQL 復(fù)制主要有兩種模式:同步和異步。同步復(fù)制允許同時(shí)將數(shù)據(jù)寫入主服務(wù)器和從服務(wù)器,而異步復(fù)制確保數(shù)據(jù)先寫入主服務(wù)器,然后再復(fù)制到從服務(wù)器。
在同步模式復(fù)制中,只有當(dāng)這些更改已復(fù)制到所有副本時(shí),主數(shù)據(jù)庫上的事務(wù)才被視為完成。副本服務(wù)器必須始終可用,以便在主服務(wù)器上完成事務(wù)。同步復(fù)制模式用于具有即時(shí)故障轉(zhuǎn)移要求的高端事務(wù)環(huán)境。
在異步模式下,當(dāng)只在主服務(wù)器上完成更改時(shí),可以聲明主服務(wù)器上的事務(wù)已完成。這些更改隨后會(huì)及時(shí)復(fù)制到副本中。副本服務(wù)器可以在一段時(shí)間內(nèi)保持不同步,稱為復(fù)制滯后。在崩潰的情況下,可能會(huì)發(fā)生數(shù)據(jù)丟失,但異步復(fù)制提供的開銷很小,因此在大多數(shù)情況下是可以接受的(不會(huì)使主服務(wù)器負(fù)擔(dān)過重)。
如何設(shè)置 PostgreSQL 復(fù)制
接下來,我們將演示如何在 Linux 操作系統(tǒng)上設(shè)置 PostgreSQL 復(fù)制過程。對于本例,我們將使用 Ubuntu 18.04 LTS 和 PostgreSQL 10。
一、安裝
通過以下步驟在 Linux 上安裝 PostgreSQL:
- 首先,通過在終端中鍵入以下命令來導(dǎo)入 PostgreSQL 簽名密鑰
- 然后,添加 PostgreSQL 存儲(chǔ)庫:
- 更新存儲(chǔ)庫索引:
- 使用 apt 命令安裝 PostgreSQL 包:
- 最后,使用以下命令為 PostgreSQL 用戶設(shè)置密碼:
在進(jìn)行 PostgreSQL 復(fù)制過程之前,主服務(wù)器和備份服務(wù)器都必須安裝 PostgreSQL。
在兩臺(tái)服務(wù)器上設(shè)置 PostgreSQL 后,可以繼續(xù)進(jìn)行主服務(wù)器和備份服務(wù)器的復(fù)制設(shè)置。
二、主服務(wù)器配置
- 首先,使用以下命令登錄到 PostgreSQL 數(shù)據(jù)庫:
- 使用以下命令創(chuàng)建復(fù)制用戶:
- 在 Ubuntu 中使用任何 nano 應(yīng)用程序編輯pg_hba.cnf并添加以下配置:
- 使用以下命令配置該文件:
- 打開并編輯postgresql.conf,并進(jìn)行以下配置:
配置如下:
- 最后,在主服務(wù)器中重啟 PostgreSQL:
至此,主服務(wù)器配置已經(jīng)完成。
三、備份服務(wù)器配置
- 使用以下命令登錄到 PostgreSQL RDMS:
- 停止 PostgreSQL 服務(wù),使用以下命令對其進(jìn)行處理:
- 使用以下命令編輯pg_hba.conf文件并添加以下配置:
- 在備份服務(wù)器打開并編輯postgresql.conf并放入以下配置,如果有注釋則取消注釋:
SecondaryIP是從服務(wù)器的地址。
- 訪問備份服務(wù)器中的 PostgreSQL 數(shù)據(jù)目錄并刪除所有內(nèi)容:
- 將 PostgreSQL 主服務(wù)器數(shù)據(jù)目錄文件復(fù)制到 PostgreSQL 從服務(wù)器數(shù)據(jù)目錄,并在從服務(wù)器中寫入以下命令:
- 輸入主服務(wù)器 PostgreSQL 密碼并按回車鍵。接下來,為恢復(fù)配置添加以下命令:
這里YOUR_PASSWORD是主服務(wù)器 PostgreSQL 創(chuàng)建的復(fù)制用戶的密碼。
- 設(shè)置密碼后,必須重新啟動(dòng)備份 PostgreSQL 數(shù)據(jù)庫:
四、測試配置是否成功
現(xiàn)在已經(jīng)執(zhí)行完了這些配置,讓我們測試復(fù)制過程并觀察從服務(wù)器數(shù)據(jù)庫是否正常。
首先,我們在主服務(wù)器中創(chuàng)建一個(gè)表,并觀察它是否反映在備份服務(wù)器上。
- 由于我們在主服務(wù)器中創(chuàng)建表,因此需要登錄到主服務(wù)器:
- 現(xiàn)在我們創(chuàng)建一個(gè)名為“testtable”的簡單表,并通過在終端中運(yùn)行以下 PostgreSQL 查詢將數(shù)據(jù)插入表中:
- 登錄從服務(wù)器觀察從服務(wù)器PostgreSQL數(shù)據(jù)庫:
- 現(xiàn)在,檢查表 'testtable' 是否存在,并且可以通過在終端中運(yùn)行以下 PostgreSQL 查詢來返回?cái)?shù)據(jù)。
查詢結(jié)果如下:
那么測試成功,主服務(wù)器數(shù)據(jù)已經(jīng)同步到從服務(wù)器上了。
PostgreSQL 手動(dòng)故障轉(zhuǎn)移步驟
讓我們回顧一下 PostgreSQL 手動(dòng)故障轉(zhuǎn)移的步驟:
- 使用非常規(guī)手段將主服務(wù)器崩潰。
- 通過在從服務(wù)器上運(yùn)行以下命令來提升從服務(wù)(切為主服務(wù)):
- 連接到提升后的從服務(wù)并插入一行:
如果插入正常,則從服務(wù)(以前是只讀服務(wù))已提升為新的主服務(wù)。
如何在 PostgreSQL 中自動(dòng)進(jìn)行故障轉(zhuǎn)移
設(shè)置自動(dòng)故障轉(zhuǎn)移很容易,需要使用到 EDB PostgreSQL 故障轉(zhuǎn)移管理器 (EFM)。在每個(gè)主節(jié)點(diǎn)和備用節(jié)點(diǎn)上下載并安裝 EFM 后,你可以創(chuàng)建一個(gè) EFM 集群,該集群由一個(gè)主節(jié)點(diǎn)、一個(gè)或多個(gè)備用節(jié)點(diǎn)以及一個(gè)可選的 Witness 節(jié)點(diǎn)組成,該節(jié)點(diǎn)在發(fā)生故障時(shí)確認(rèn)斷言。
EFM 持續(xù)監(jiān)控系統(tǒng)運(yùn)行狀況并根據(jù)系統(tǒng)事件發(fā)送電子郵件警報(bào)。當(dāng)發(fā)生故障時(shí),它會(huì)自動(dòng)切換到最新的備用服務(wù)并重新配置所有其他備用服務(wù)以識別新的主節(jié)點(diǎn)。
它還會(huì)重新配置負(fù)載平衡器(例如 pgPool)并防止發(fā)生“裂腦”(當(dāng)兩個(gè)節(jié)點(diǎn)都認(rèn)為它們是主節(jié)點(diǎn)時(shí))。
總結(jié)
由于存儲(chǔ)數(shù)據(jù)量大,可伸縮性和安全性已成為數(shù)據(jù)庫管理中最重要的兩個(gè)標(biāo)準(zhǔn),尤其是在事務(wù)環(huán)境中。雖然我們可以通過向現(xiàn)有節(jié)點(diǎn)添加更多資源/硬件來垂直提高可擴(kuò)展性,但這并不總是可行的,因?yàn)樘砑有掠布切枰杀镜摹?/p>
因此,就需要 PostgreSQL 復(fù)制發(fā)揮作用了,它實(shí)現(xiàn)了水平可擴(kuò)展,即向現(xiàn)有網(wǎng)絡(luò)節(jié)點(diǎn)添加更多節(jié)點(diǎn),而不是增加現(xiàn)有節(jié)點(diǎn)的硬件配置。