通過搭建PostgreSQL主從架構,實現讀寫分離,將讀操作分流至從節點,提升查詢效能。同時,從節點可作為主節點的資料副本,在主節點故障時用於資料恢複或手動故障切換,從而提高系統可用性。
方案架構
工作流程說明
資料寫入與產生預寫記錄檔(Write-Ahead Log,WAL):主節點處理寫事務,並將資料變更記錄到WAL。
傳輸WAL日誌:主節點的
walsender進程通過流式複製,將WAL即時傳輸到從節點的walreceiver進程。資料同步:從節點的
walreceiver進程接收WAL,恢複進程讀取WAL並將其中的資料變更寫入從節點資料庫,實現與主節點的資料同步。提供唯讀服務:從節點在持續同步的同時,對外提供唯讀查詢服務。
實施步驟
步驟一:準備 ECS 執行個體和網路環境
建立兩台ECS執行個體,分別作為主節點和從節點。執行個體配置:
規格:ecs.c7.large(2vCPU,4GiB)或更高規格。
鏡像:Alibaba Cloud Linux 3.2104 LTS 64位/CentOS 8.x 64位/Ubuntu 22.04 64位。
網路:Virtual Private Cloud,位於同一地區和可用性區域,以降低網路延遲,確保資料同步效能。需開通公網存取權限,用於下載安裝包。
高可用性主要通過主從架構實現,從節點作為資料副本用於故障恢複。
安全性群組:配置相同的安全性群組。
樣本私網IP:
主節點私網IP樣本:
192.168.1.10從節點私網IP樣本:
192.168.1.20
步驟二:配置PostgreSQL主節點
Alibaba Cloud Linux 3/CentOS 8
以PostgreSQL18為例。
登入ECS執行個體。
訪問ECS控制台-執行個體。在頁面左側頂部,選擇目標資源所在的資源群組和地區。
進入目標執行個體詳情頁,單擊遠端連線,選擇通過Workbench遠端連線。根據頁面提示登入,進入終端頁面。
安裝PostgreSQL18。配置YUM倉庫並安裝服務端軟體包。
# 判斷作業系統類型,如果是CentOS 8則禁用系統預設的PostgreSQL模組 if [ -f /etc/os-release ]; then . /etc/os-release if [ "$ID" = "centos" ] && [ "${VERSION_ID%%.*}" = "8" ]; then sudo dnf --assumeyes module disable postgresql fi fi # 添加 PostgreSQL 官方 YUM 倉庫 sudo rpm -Uvh http://mirrors.cloud.aliyuncs.com/postgresql/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm #替換倉庫地址為阿里雲鏡像源以加速下載 sudo sed -i "s@https://download.postgresql.org/pub@http://mirrors.cloud.aliyuncs.com/postgresql@g" /etc/yum.repos.d/pgdg-redhat-all.repo sudo sed -i "s@\$releasever@8@g" /etc/yum.repos.d/pgdg-redhat-all.repo # 安裝PostgreSQL18服務端 sudo dnf install -y postgresql18-server初始化資料庫。建立資料目錄
/var/lib/pgsql/18/data/並產生預設的設定檔。sudo /usr/pgsql-18/bin/postgresql-18-setup initdb編輯
/var/lib/pgsql/18/data/postgresql.conf檔案,配置監聽地址、WAL層級等參數。# 監聽來自所有網路介面的串連。 listen_addresses = '*' # 設定WAL層級為replica。 wal_level = replica # 設定最大允許的流複製串連數,應大於或等於從節點數量。 max_wal_senders = 3 # 啟用WAL歸檔。當從節點長時間掉線導致主節點WAL被清理時,從節點可自動從歸檔恢複。 archive_mode = on # 歸檔方案配置,此處樣本為歸檔至/mnt/server/archivedir/。 archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'啟動服務並建立PostgreSQL使用者和複製槽。
啟動PostgreSQL服務並設定開機自啟。
sudo systemctl enable postgresql-18.service sudo systemctl start postgresql-18.service建立一個具有
REPLICATION許可權的PostgreSQL使用者。sudo -u postgres psql -c "CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'YOUR_SECURE_PASSWORD';"建立物理複製槽,當從節點因網路中斷或停機維護導致離線時,主節點會自動清理舊的WAL日誌。建立複製槽可強制主節點保留這些日誌,確保從節點恢複後能繼續同步。
sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('secondary_slot');"
配置
pg_hba.conf檔案以允許從節點串連。在/var/lib/pgsql/18/data/pg_hba.conf檔案末尾添加認證規則,允許從節點以PostgreSQL使用者的身份串連。# TYPE DATABASE USER ADDRESS METHOD host replication replica_user 192.168.1.20/32 scram-sha-256replica_user:PostgreSQL使用者名稱。192.168.1.20:從節點的私網IP。
重啟服務使配置生效。
sudo systemctl restart postgresql-18.service
Ubuntu/Debian
Ubuntu版本需在22.04及以上,Debian版本需在11及以上,本文以PostgreSQL18為例。
登入ECS執行個體。
訪問ECS控制台-執行個體。在頁面左側頂部,選擇目標資源所在的資源群組和地區。
進入目標執行個體詳情頁,單擊遠端連線,選擇通過Workbench遠端連線。根據頁面提示登入,進入終端頁面。
安裝PostgreSQL18。配置PostgreSQL的APT倉庫並安裝軟體包。
# 添加 PostgreSQL 官方 APT 倉庫並使用阿里雲鏡像 sudo sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/postgresql.gpg] http://mirrors.cloud.aliyuncs.com/postgresql/repos/apt/ $(lsb_release -sc)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' # 匯入倉庫簽名密鑰 wget -qO - http://mirrors.cloud.aliyuncs.com/postgresql/repos/apt/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg # 更新軟體包列表並安裝 sudo apt-get update sudo apt-get install -y postgresql-18編輯
/etc/postgresql/18/main/postgresql.conf檔案,配置監聽地址、WAL層級等參數。# 監聽來自所有網路介面的串連。 listen_addresses = '*' # 設定WAL層級為replica。 wal_level = replica # 設定最大允許的流複製串連數,應大於或等於從節點數量。 max_wal_senders = 3 # 啟用WAL歸檔。當從節點長時間掉線導致主節點WAL被清理時,從節點可自動從歸檔恢複。 archive_mode = on # 歸檔方案配置,此處樣本為歸檔至/mnt/server/archivedir/。 archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'啟動服務並建立PostgreSQL使用者和複製槽。
啟動PostgreSQL服務並設定開機自啟。
sudo systemctl enable postgresql.service sudo systemctl start postgresql.service建立一個具有
REPLICATION許可權的PostgreSQL使用者。sudo -u postgres psql -c "CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'YOUR_SECURE_PASSWORD';"建立物理複製槽,當從節點因網路中斷或停機維護導致離線時,主節點會自動清理舊的WAL日誌。建立複製槽可強制主節點保留這些日誌,確保從節點恢複後能繼續同步。
sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('secondary_slot');"
配置
pg_hba.conf檔案以允許從節點串連在/etc/postgresql/18/main/pg_hba.conf檔案末尾添加認證規則,允許從節點以PostgreSQL使用者的身份串連。# TYPE DATABASE USER ADDRESS METHOD host replication replica_user 192.168.1.20/32 scram-sha-256replica_user:PostgreSQL使用者名稱。192.168.1.20:從節點的私網IP。
重啟服務使配置生效。
sudo systemctl restart postgresql.service
Alibaba Cloud Linux 2/CentOS 7
以PostgreSQL15為例。
登入ECS執行個體。
訪問ECS控制台-執行個體。在頁面左側頂部,選擇目標資源所在的資源群組和地區。
進入目標執行個體詳情頁,單擊遠端連線,選擇通過Workbench遠端連線。根據頁面提示登入,進入終端頁面。
安裝PostgreSQL15。配置YUM倉庫並安裝服務端軟體包。
# 添加 PostgreSQL 官方 YUM 倉庫 sudo rpm -Uvh http://mirrors.cloud.aliyuncs.com/postgresql/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm #替換倉庫地址為阿里雲鏡像源以加速下載 sudo sed -i "s@https://download.postgresql.org/pub@http://mirrors.cloud.aliyuncs.com/postgresql@g" /etc/yum.repos.d/pgdg-redhat-all.repo sudo sed -i "s@\$releasever@7@g" /etc/yum.repos.d/pgdg-redhat-all.repo # 安裝PostgreSQL15服務端 sudo yum install -y postgresql15-server初始化資料庫。建立資料目錄
/var/lib/pgsql/15/data/並產生預設的設定檔。sudo /usr/pgsql-15/bin/postgresql-15-setup initdb編輯
/var/lib/pgsql/15/data/postgresql.conf檔案,配置監聽地址、WAL層級等參數。# 監聽來自所有網路介面的串連。 listen_addresses = '*' # 設定WAL層級為replica。 wal_level = replica # 設定最大允許的流複製串連數,應大於或等於從節點數量。 max_wal_senders = 3 # 啟用WAL歸檔。當從節點長時間掉線導致主節點WAL被清理時,從節點可自動從歸檔恢複。 archive_mode = on # 歸檔方案配置,此處樣本為歸檔至/mnt/server/archivedir/。 archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'啟動服務並建立PostgreSQL使用者和複製槽。
啟動PostgreSQL服務並設定開機自啟。
sudo systemctl enable postgresql-15.service sudo systemctl start postgresql-15.service建立一個具有
REPLICATION許可權的PostgreSQL使用者。sudo -u postgres psql -c "CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'YOUR_SECURE_PASSWORD';"建立物理複製槽,當從節點因網路中斷或停機維護導致離線時,主節點會自動清理舊的WAL日誌。建立複製槽可強制主節點保留這些日誌,確保從節點恢複後能繼續同步。
sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('secondary_slot');"
配置
pg_hba.conf檔案以允許從節點串連。在/var/lib/pgsql/15/data/pg_hba.conf檔案末尾添加認證規則,允許從節點以PostgreSQL使用者的身份串連。# TYPE DATABASE USER ADDRESS METHOD host replication replica_user 192.168.1.20/32 scram-sha-256replica_user:PostgreSQL使用者名稱。192.168.1.20:為從節點的私網IP。scram-sha-256:一種比md5更安全的密碼認證方法。
重啟服務使配置生效。
sudo systemctl restart postgresql-15.service
步驟三:配置PostgreSQL從節點
Alibaba Cloud Linux 3/CentOS 8
安裝PostgreSQL18。配置YUM倉庫並安裝服務端軟體包。
# 判斷作業系統類型,如果是CentOS 8則禁用系統預設的PostgreSQL模組 if [ -f /etc/os-release ]; then . /etc/os-release if [ "$ID" = "centos" ] && [ "${VERSION_ID%%.*}" = "8" ]; then sudo dnf --assumeyes module disable postgresql fi fi # 添加 PostgreSQL 官方 YUM 倉庫 sudo rpm -Uvh http://mirrors.cloud.aliyuncs.com/postgresql/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm #替換倉庫地址為阿里雲鏡像源以加速下載 sudo sed -i "s@https://download.postgresql.org/pub@http://mirrors.cloud.aliyuncs.com/postgresql@g" /etc/yum.repos.d/pgdg-redhat-all.repo sudo sed -i "s@\$releasever@8@g" /etc/yum.repos.d/pgdg-redhat-all.repo # 安裝PostgreSQL18服務端 sudo dnf install -y postgresql18-server在
postgres使用者的家目錄下建立.pgpass檔案,用於自動提供PostgreSQL使用者的密碼。切換到postgres使用者。
sudo su - postgres建立並配置
.pgpass檔案。echo "192.168.1.10:5432:replication:replica_user:YOUR_SECURE_PASSWORD" > ~/.pgpass chmod 600 ~/.pgpass退出postgres使用者。
exit
從主節點複製資料。使用
pg_basebackup工具從主節點擷取資料。重要此操作會將主節點的資料全量同步並覆蓋至目標資料目錄
/var/lib/pgsql/18/data/。請確保該目錄內無資料。# 以 postgres 使用者身份執行基礎備份 sudo -u postgres pg_basebackup -h 192.168.1.10 -D /var/lib/pgsql/18/data/ -U replica_user -P -v --wal-method=stream-h: 主節點IP。-D: 從節點資料目錄。-U: PostgreSQL使用者名稱。
建立
standby.signal檔案以啟用備庫模式。此空檔案用於告知PostgreSQL在啟動時進入備用(standby)模式,而非作為主庫啟動。sudo -u postgres touch /var/lib/pgsql/18/data/standby.signal配置
postgresql.conf檔案以串連主庫。編輯/var/lib/pgsql/18/data/postgresql.conf檔案,添加主庫串連資訊和熱備配置。primary_conninfo中無需包含密碼,PostgreSQL會自動使用.pgpass檔案中的密碼。# 主節點串連資訊,用於建立流複製 # slot_name 必須與主節點建立的複製槽名稱一致 primary_conninfo = 'host=192.168.1.10 port=5432 user=replica_user application_name=secondary_node1' # 指定複製槽名稱,必須與主節點建立的複製槽名稱一致 primary_slot_name = 'secondary_slot' # 開啟熱備模式,允許在同步時提供唯讀查詢 hot_standby = on啟動從節點服務。
sudo systemctl enable postgresql-18.service sudo systemctl start postgresql-18.service
Ubuntu/Debian
安裝PostgreSQL18。配置PostgreSQL的APT倉庫並安裝軟體包。
# 添加 PostgreSQL 官方 APT 倉庫並使用阿里雲鏡像 sudo sh -c 'echo "deb [signed-by=/etc/apt/trusted.gpg.d/postgresql.gpg] http://mirrors.cloud.aliyuncs.com/postgresql/repos/apt/ $(lsb_release -sc)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' # 匯入倉庫簽名密鑰 wget -qO - http://mirrors.cloud.aliyuncs.com/postgresql/repos/apt/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg # 更新軟體包列表並安裝 sudo apt-get update sudo apt-get install -y postgresql-18在
postgres使用者的家目錄下建立.pgpass檔案,用於自動提供PostgreSQL使用者的密碼。切換到postgres使用者。
sudo su - postgres建立並配置
.pgpass檔案。echo "192.168.1.10:5432:replication:replica_user:YOUR_SECURE_PASSWORD" > ~/.pgpass chmod 600 ~/.pgpass退出postgres使用者。
exit
從主節點複製資料。使用
pg_basebackup工具從主節點擷取資料。重要此操作會將主節點的資料全量同步並覆蓋至目標資料目錄
/var/lib/postgresql/18/main/。請確保該目錄內無資料。# 以 postgres 使用者身份執行基礎備份 sudo -u postgres pg_basebackup -h 192.168.1.10 -D /var/lib/postgresql/18/main/ -U replica_user -P -v --wal-method=stream-h: 主節點IP。-D: 從節點資料目錄。-U: PostgreSQL使用者名稱。
建立
standby.signal檔案以啟用備庫模式。此空檔案用於告知PostgreSQL在啟動時進入備用(standby)模式,而非作為主庫啟動。sudo -u postgres touch /var/lib/postgresql/18/main/standby.signal配置
postgresql.conf檔案以串連主庫。編輯/etc/postgresql/18/main/postgresql.conf檔案,添加主庫串連資訊和熱備配置。primary_conninfo中無需包含密碼,PostgreSQL會自動使用.pgpass檔案中的密碼。# 主節點串連資訊,用於建立流複製 # slot_name 必須與主節點建立的複製槽名稱一致 primary_conninfo = 'host=192.168.1.10 port=5432 user=replica_user application_name=secondary_node1' # 指定複製槽名稱,必須與主節點建立的複製槽名稱一致 primary_slot_name = 'secondary_slot' # 開啟熱備模式,允許在同步時提供唯讀查詢 hot_standby = on啟動從節點服務。
sudo systemctl enable postgresql.service sudo systemctl start postgresql.service
Alibaba Cloud Linux 2/CentOS 7
安裝PostgreSQL15。配置YUM倉庫並安裝服務端軟體包。
# 添加 PostgreSQL 官方 YUM 倉庫 sudo rpm -Uvh http://mirrors.cloud.aliyuncs.com/postgresql/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm #替換倉庫地址為阿里雲鏡像源以加速下載 sudo sed -i "s@https://download.postgresql.org/pub@http://mirrors.cloud.aliyuncs.com/postgresql@g" /etc/yum.repos.d/pgdg-redhat-all.repo sudo sed -i "s@\$releasever@7@g" /etc/yum.repos.d/pgdg-redhat-all.repo # 安裝PostgreSQL15服務端 sudo yum install -y postgresql15-server在
postgres使用者的家目錄下建立.pgpass檔案,用於自動提供PostgreSQL使用者的密碼。切換到postgres使用者。
sudo su - postgres建立並配置
.pgpass檔案。echo "192.168.1.10:5432:replication:replica_user:YOUR_SECURE_PASSWORD" > ~/.pgpass chmod 600 ~/.pgpass退出postgres使用者。
exit
從主節點複製資料。使用
pg_basebackup工具從主節點擷取資料。重要此操作會將主節點的資料全量同步並覆蓋至目標資料目錄
/var/lib/pgsql/15/data/。請確保該目錄內無資料。# 以 postgres 使用者身份執行基礎備份 sudo -u postgres pg_basebackup -h 192.168.1.10 -D /var/lib/pgsql/15/data/ -U replica_user -P -v --wal-method=stream-h: 主節點IP。-D: 從節點資料目錄。-U: PostgreSQL使用者名稱。
建立
standby.signal檔案以啟用備庫模式。此空檔案用於告知PostgreSQL在啟動時進入備用(standby)模式,而非作為主庫啟動。sudo -u postgres touch /var/lib/pgsql/15/data/standby.signal配置
postgresql.conf檔案以串連主庫。編輯/var/lib/pgsql/15/data/postgresql.conf檔案,添加主庫串連資訊和熱備配置。primary_conninfo中無需包含密碼,PostgreSQL會自動使用.pgpass檔案中的密碼。# 主節點串連資訊,用於建立流複製 # slot_name 必須與主節點建立的複製槽名稱一致 primary_conninfo = 'host=192.168.1.10 port=5432 user=replica_user application_name=secondary_node1' # 指定複製槽名稱,必須與主節點建立的複製槽名稱一致 primary_slot_name = 'secondary_slot' # 開啟熱備模式,允許在同步時提供唯讀查詢 hot_standby = on啟動從節點服務。
sudo systemctl enable postgresql-15.service sudo systemctl start postgresql-15.service
步驟四:驗證主從複製狀態
檢查複製相關進程。
主從節點上負責資料同步的
walsender和walreceiver進程已啟動,表明複製串連已建立。在主節點上,檢查
walsender進程:ps aux | grep "walsender.*streaming"預期輸出類似:
postgres: walsender replica_user 192.168.1.20(xxxxx) streaming。在從節點上,檢查
walreceiver進程:ps aux | grep "walreceiver.*streaming"預期輸出類似:
postgres: walreceiver streaming。
執行資料同步測試。
在主節點寫入資料,然後在從節點驗證資料是否同步,以確認複製鏈路正常。
在主節點上建立一個測試表並插入資料。
sudo -u postgres psql -c "CREATE TABLE replication_test (id serial primary key, test_data text, created_at timestamptz default now());" sudo -u postgres psql -c "INSERT INTO replication_test (test_data) VALUES ('hello replication');"在從節點上查詢該表,驗證資料是否已同步。
# 主從同步通常存在一定延時,請等待幾秒鐘後再查詢 sudo -u postgres psql -c "SELECT * FROM replication_test;"如果能查詢到已插入的資料,則表示主從複製已成功建立。