數據庫復制是將數據從中央或主服務器復制到多個稱為副本的服務器的過程。主服務器接受讀取和寫入操作,而副本服務器提供只讀事務。主服務器和副本共同構成一個數據庫集群。數據庫復制的目標是確保數據的冗余、一致性、高可用性和可訪問性,尤其是在高流量、關鍵任務應用程序中。
PostgreSQL 提供了兩種復制方法:物理(即流式)復制和邏輯復制。兩者都是不同用例的理想選擇,用戶可以根據最終目標選擇其中之一。讓我們看看這些復制方法中的每一種。
物理 PostgreSQL 復制
這是 PostgreSQL 中最常見的復制類型。物理復制維護集群整個數據的完整副本。它使用精確的塊地址并采用逐字節(jié)復制。簡單來說,主服務器上的整個數據集都被復制到充當備用節(jié)點的副本。
物理復制不會復制主數據庫集群的特定對象,例如表中的單行數據。相反,它在磁盤塊級別上工作,并將所有數據鏡像到副本節(jié)點;包括每個數據庫中的所有表。此復制要求所有副本都相同。
用例:
- 它主要用于災難恢復設置和備份,因為所有副本都是相同的。
- 處理大量數據時推薦使用
優(yōu)點
- 它很容易實現,因為所有的數據庫集群都是相同的。
- 它確保了任何時候的數據一致性和高可用性,因為所有副本都持有相同的數據副本。
- 它非常適合對副本進行只讀操作。
- 它非常高效,因為它不需要任何特殊處理。
缺點
- 這是帶寬密集型的,因為要復制整個數據,而不僅僅是主集群的一小部分。
- 它不提供多主數據庫復制。
邏輯 PostgreSQL 復制
邏輯復制最早是在 PostgreSQL 9.0 中引入的。它通過復制數據對象及其基于唯一標識符(如主鍵)的更改來工作。簡單來說,邏輯復制以基于行的模型復制數據庫對象,而不是將所有內容發(fā)送到副本節(jié)點的物理復制。
因此,與物理復制相反,邏輯復制提供了對數據復制的細粒度控制。
用例:
邏輯復制的典型用例包括:
- 在不同主要版本的 PostgreSQL 之間復制。
- 在不同平臺上托管的 PostgreSQL 實例之間進行復制,例如從 Linux 到 Windows。
- 將數據庫中的增量更改實時發(fā)送到副本。
- 向不同的用戶組授予對復制數據的訪問權限。
優(yōu)點
- 它是備份增量數據的理想選擇。
- 由于更好的性能和低數據丟失,最推薦用于高可用性集群。
- 帶寬優(yōu)化,因為只有提交的數據事務的行更改才會發(fā)送到副本,而不是整個數據塊。
- 用于使用物理復制無法實現的多主復制。
- 支持跨各種操作系統(tǒng)平臺的復制,例如 Linux 到 Windows,反之亦然。
缺點
- 它無法實時傳輸大量交易。
- 復制過程比物理復制更復雜。
- 副本節(jié)點上的資源利用率高。
在 Ubuntu 22.04 上設置物理 PostgreSQL 復制
為了演示復制過程,您需要一個主節(jié)點和一個將在其上進行復制的副本節(jié)點。下面是我們的實驗室設置,我們將使用 Ubuntu 22.04 作為首選操作系統(tǒng)。
主節(jié)點:IP:194.195.208.82 操作系統(tǒng):Ubuntu 22.04 服務器
副本節(jié)點:IP:139.144.169.79 操作系統(tǒng):Ubuntu 22.04 服務器
第 1 步:安裝 PostgreSQL 服務器
第一步是在主節(jié)點和副本節(jié)點上安裝 PostgreSQL。請注意,您需要在兩個節(jié)點上安裝相同版本的 PostgreSQL 才能進行邏輯復制。
在撰寫本指南時,最新版本的 PostgreSQL 是 PostgreSQL 14。
首先,通過 SSH 登錄到您的服務器并刷新存儲庫。
sudo apt update
接下來,按如下方式安裝 PostgreSQL 數據庫服務器。
sudo apt install postgresql postgresql-contrib -y
默認情況下,PostgreSQL 守護程序會在安裝后自動運行。您可以使用以下命令驗證這一點:
sudo systemctl status postgresql
下面的輸出確認 PostgreSQL 服務已啟動并正在運行。
此外,考慮使服務在系統(tǒng)啟動時啟動,如下所示。
sudo systemctl enable postgresql
第二步:配置主節(jié)點
接下來,以用戶身份登錄主節(jié)點 (194.195.208.82),postgres該用戶是每次新安裝 PostgreSQL 時創(chuàng)建的默認用戶。
sudo -u postgres psql
您需要創(chuàng)建一個復制用戶,用于從主節(jié)點啟動復制過程。
因此,運行以下命令創(chuàng)建復制用戶并分配復制權限。在此命令中,replica_user?是復制用戶,而P@ssword321是用戶的密碼。請務必提供一個強密碼,這與我們使用的純粹用于演示目的的密碼不同。
CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'P@ssword321';
然后從 PostgreSQL 提示符注銷
postgres-# \q
接下來,您需要對主配置文件進行一些調整。使用您喜歡的文本編輯器訪問以下配置文件:
sudo vim /etc/postgresql/14/main/postgresql.conf
打開文件后,向下滾動并找到該listen_addresses指令。該指令指定 PostgreSQL 數據庫服務器偵聽連接的主機。
通過刪除#符號取消注釋該指令,并替換localhost為用單引號括起來的服務器 IP 地址,如下所示:
接下來,找到該wal_level指令。該設置指定要寫入預寫日志 (WAL) 文件的信息量。
取消注釋該行并將其設置logical為如圖所示。
接下來,找到該wal_log_hints指令。默認情況下,它設置為off。
當設置on為該值時,允許 PostgreSQL 服務器在頁面的第一次修改期間將每個磁盤頁面的全部內容寫入 WAL 文件。
取消注釋并將其設置為on.
這就是此配置文件中所需更改的全部內容。保存更改并退出。
接下來,訪問/etc/postgresql/14/main/pg_hba.conf配置文件。
sudo vim /etc/postgresql/14/main/pg_hba.conf
將此行附加到配置文件的末尾。這允許副本 (139.144.169.79) 使用replica_user.
host replication replica_user 139.144.169.79/24 md5
保存更改并關閉文件。重啟 PostgreSQL 服務。
sudo systemctl restart postgresql
第三步:配置副本節(jié)點
在副本節(jié)點可以開始從主節(jié)點復制數據之前,您需要創(chuàng)建主節(jié)點數據目錄到副本數據目錄的副本。為此,首先,停止副本節(jié)點上的 PostgreSQL 服務。
sudo systemctl stop postgresql
接下來,刪除副本數據目錄中的所有文件,以便從頭開始并為主節(jié)點數據目錄騰出空間。
sudo rm -rv /var/lib/postgresql/14/main/
現在pg_basebackup?如圖所示運行該實用程序,將數據從主節(jié)點復制到副本節(jié)點。
sudo pg_basebackup -h 194.195.208.82 -U replica_user -X stream -C -S replica_1 -v -R -W -D /var/lib/postgresql/14/main/
讓我們看一下命令中使用的選項:
- -h:此選項指定主機,在本例中為主節(jié)點的 IP 地址。
- -U:該選項指定復制用戶。這是在主節(jié)點上配置的用戶,副本節(jié)點將使用該用戶連接到它。在我們的例子中,復制用戶被稱為replica_user.
- -X:該選項與流值一起指示pg_basebackup實用程序流式傳輸并將 WAL 文件包含在備份中。
- -C:該選項允許您在備份開始之前創(chuàng)建一個復制槽。該選項與-S指定插槽名稱的選項一起使用。在這種情況下,我們的復制槽稱為replica_1。
- -v:這會打印出詳細的輸出,指示從主節(jié)點到副本的備份過程的進度。
- -R:該選項創(chuàng)建兩個文件;一個名為的空恢復配置文件standby.signal和一個名為的主節(jié)點連接設置文件postgresql.auto.conf.該standby.signal文件包含有關主節(jié)點的連接信息,該postgresql.auto.conf?文件通知您的副本集群它應該作為備用服務器運行。
- -W:這會提示您為replica_user?復制用戶提供密碼。
- -D:最后,該-D選項允許您包含要導出備份文件的目錄。在這個例子中,我們將數據放在/var/lib/postgresql/14/main/副本節(jié)點的目錄下。
這是運行復制命令的輸出。
之后,在副本上執(zhí)行以下命令以將數據目錄的所有權授予 postgres 用戶。
sudo chown postgres -R /var/lib/postgresql/14/main/
現在,啟動 PostgreSQL 服務器。副本現在將以熱備用模式運行。
sudo systemctl start postgresql
第 4 步:測試復制設置
至此,主節(jié)點的數據目錄已經成功備份到副本上,副本開始雙機熱備。
剩下的部分是測試復制是否按預期工作。如果副本在熱備模式下成功運行,那么它應該連接到主服務器上的主數據庫集群。
要驗證副本是否連接到主節(jié)點并且主節(jié)點正在流式傳輸,請登錄到主服務器并切換到postgres?用戶。
sudo -u postgres psql
接下來,查詢pg_stat_replication包含有關復制的重要信息的表。在此命令中,我們正在檢索有關副本的 IP 地址和主服務器狀態(tài)的信息。
SELECT client_addr, state FROM pg_stat_replication;
您應該得到以下輸出確認您的設置正在運行。
為了證實這一點,我們將創(chuàng)建一個測試數據庫并添加一個包含幾條記錄的表,然后驗證數據庫是否已在副本上復制。
我們將創(chuàng)建一個名為students.
CREATE DATABASE students_db;
接下來,切換到數據庫。
\c students_db;
輸出
You are now connected to database "students_db" as user "postgres".
進入數據庫后,創(chuàng)建一個student_details使用以下模式調用的表。
CREATE TABLE student_details (first_name VARCHAR(15), last_name VARCHAR(15) , email VARCHAR(40) );
然后將以下記錄插入表中。
INSERT INTO student_details (first_name, last_name, email) VALUES ('Arthur', 'Spencer', 'arthurspencer@gmail.com');
您可以查詢表以確認插入的記錄,如圖所示。
SELECT * FROM student_details;
現在轉到副本節(jié)點并切換到postgres?用戶。
sudo -u postgres psql
在 shell 上,驗證剛才在主節(jié)點中創(chuàng)建的數據庫是否存在。
postgres=# \l
現在,切換到數據庫。
\c students_db;
查詢表中存儲的所有記錄。
SELECT * FROM student_details;
您應該得到與您在主節(jié)點中創(chuàng)建的記錄完全相同的記錄,如下所示。
這就證明復制成功了!您可以繼續(xù)在主服務器上添加更多記錄,然后將這些記錄復制或復制到副本節(jié)點。
結論
在本教程中,我們了解了 PostgreSQL 提供的兩種復制方法及其優(yōu)缺點。我們更進一步,使用 PostgreSQL 邏輯模型創(chuàng)建了一個復制集群,并演示了從主節(jié)點到副本節(jié)點的數據復制。前往官方文檔以更全面地了解 PostgreSQL 中的復制。