全部產品
Search
文件中心

Elastic Compute Service:搭建PostgreSQL主從架構

更新時間:Dec 27, 2025

通過搭建PostgreSQL主從架構,實現讀寫分離,將讀操作分流至從節點,提升查詢效能。同時,從節點可作為主節點的資料副本,在主節點故障時用於資料恢複或手動故障切換,從而提高系統可用性。

方案架構

image

工作流程說明

  1. 資料寫入與產生預寫記錄檔(Write-Ahead Log,WAL):主節點處理寫事務,並將資料變更記錄到WAL。

  2. 傳輸WAL日誌:主節點的walsender進程通過流式複製,將WAL即時傳輸到從節點的walreceiver進程。

  3. 資料同步:從節點的walreceiver進程接收WAL,恢複進程讀取WAL並將其中的資料變更寫入從節點資料庫,實現與主節點的資料同步。

  4. 提供唯讀服務:從節點在持續同步的同時,對外提供唯讀查詢服務。

實施步驟

步驟一:準備 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為例。
  1. 登入ECS執行個體。

    1. 訪問ECS控制台-執行個體。在頁面左側頂部,選擇目標資源所在的資源群組和地區。

    2. 進入目標執行個體詳情頁,單擊遠端連線,選擇通過Workbench遠端連線。根據頁面提示登入,進入終端頁面。

  2. 安裝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
  3. 初始化資料庫。建立資料目錄/var/lib/pgsql/18/data/並產生預設的設定檔。

    sudo /usr/pgsql-18/bin/postgresql-18-setup initdb
  4. 編輯/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'
  5. 啟動服務並建立PostgreSQL使用者和複製槽。

    1. 啟動PostgreSQL服務並設定開機自啟。

      sudo systemctl enable postgresql-18.service
      sudo systemctl start postgresql-18.service
    2. 建立一個具有REPLICATION許可權的PostgreSQL使用者。

      sudo -u postgres psql -c "CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'YOUR_SECURE_PASSWORD';"
    3. 建立物理複製槽,當從節點因網路中斷或停機維護導致離線時,主節點會自動清理舊的WAL日誌。建立複製槽可強制主節點保留這些日誌,確保從節點恢複後能繼續同步。

      sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('secondary_slot');"
  6. 配置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-256
    • replica_user:PostgreSQL使用者名稱。

    • 192.168.1.20:從節點的私網IP。

  7. 重啟服務使配置生效。

    sudo systemctl restart postgresql-18.service

Ubuntu/Debian

Ubuntu版本需在22.04及以上,Debian版本需在11及以上,本文以PostgreSQL18為例。
  1. 登入ECS執行個體。

    1. 訪問ECS控制台-執行個體。在頁面左側頂部,選擇目標資源所在的資源群組和地區。

    2. 進入目標執行個體詳情頁,單擊遠端連線,選擇通過Workbench遠端連線。根據頁面提示登入,進入終端頁面。

  2. 安裝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
  3. 編輯/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'
  4. 啟動服務並建立PostgreSQL使用者和複製槽。

    1. 啟動PostgreSQL服務並設定開機自啟。

      sudo systemctl enable postgresql.service
      sudo systemctl start postgresql.service
    2. 建立一個具有REPLICATION許可權的PostgreSQL使用者。

      sudo -u postgres psql -c "CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'YOUR_SECURE_PASSWORD';"
    3. 建立物理複製槽,當從節點因網路中斷或停機維護導致離線時,主節點會自動清理舊的WAL日誌。建立複製槽可強制主節點保留這些日誌,確保從節點恢複後能繼續同步。

      sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('secondary_slot');"
  5. 配置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-256
    • replica_user:PostgreSQL使用者名稱。

    • 192.168.1.20:從節點的私網IP。

  6. 重啟服務使配置生效。

    sudo systemctl restart postgresql.service

Alibaba Cloud Linux 2/CentOS 7

以PostgreSQL15為例。
  1. 登入ECS執行個體。

    1. 訪問ECS控制台-執行個體。在頁面左側頂部,選擇目標資源所在的資源群組和地區。

    2. 進入目標執行個體詳情頁,單擊遠端連線,選擇通過Workbench遠端連線。根據頁面提示登入,進入終端頁面。

  2. 安裝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
  3. 初始化資料庫。建立資料目錄/var/lib/pgsql/15/data/並產生預設的設定檔。

    sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
  4. 編輯/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'
  5. 啟動服務並建立PostgreSQL使用者和複製槽。

    1. 啟動PostgreSQL服務並設定開機自啟。

      sudo systemctl enable postgresql-15.service
      sudo systemctl start postgresql-15.service
    2. 建立一個具有REPLICATION許可權的PostgreSQL使用者。

      sudo -u postgres psql -c "CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'YOUR_SECURE_PASSWORD';"
    3. 建立物理複製槽,當從節點因網路中斷或停機維護導致離線時,主節點會自動清理舊的WAL日誌。建立複製槽可強制主節點保留這些日誌,確保從節點恢複後能繼續同步。

      sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('secondary_slot');"
  6. 配置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-256
    • replica_user:PostgreSQL使用者名稱。

    • 192.168.1.20:為從節點的私網IP。

    • scram-sha-256:一種比md5更安全的密碼認證方法。

  7. 重啟服務使配置生效。

    sudo systemctl restart postgresql-15.service

步驟三:配置PostgreSQL從節點

Alibaba Cloud Linux 3/CentOS 8

  1. 安裝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
  2. postgres使用者的家目錄下建立.pgpass檔案,用於自動提供PostgreSQL使用者的密碼。

    1. 切換到postgres使用者。

      sudo su - postgres
    2. 建立並配置.pgpass檔案。

      echo "192.168.1.10:5432:replication:replica_user:YOUR_SECURE_PASSWORD" > ~/.pgpass
      chmod 600 ~/.pgpass
    3. 退出postgres使用者。

      exit
  3. 從主節點複製資料。使用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使用者名稱。

  4. 建立standby.signal檔案以啟用備庫模式。此空檔案用於告知PostgreSQL在啟動時進入備用(standby)模式,而非作為主庫啟動。

    sudo -u postgres touch /var/lib/pgsql/18/data/standby.signal
  5. 配置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
  6. 啟動從節點服務。

    sudo systemctl enable postgresql-18.service
    sudo systemctl start postgresql-18.service

Ubuntu/Debian

  1. 安裝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
  2. postgres使用者的家目錄下建立.pgpass檔案,用於自動提供PostgreSQL使用者的密碼。

    1. 切換到postgres使用者。

      sudo su - postgres
    2. 建立並配置.pgpass檔案。

      echo "192.168.1.10:5432:replication:replica_user:YOUR_SECURE_PASSWORD" > ~/.pgpass
      chmod 600 ~/.pgpass
    3. 退出postgres使用者。

      exit
  3. 從主節點複製資料。使用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使用者名稱。

  4. 建立standby.signal檔案以啟用備庫模式。此空檔案用於告知PostgreSQL在啟動時進入備用(standby)模式,而非作為主庫啟動。

    sudo -u postgres touch /var/lib/postgresql/18/main/standby.signal
  5. 配置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
  6. 啟動從節點服務。

    sudo systemctl enable postgresql.service
    sudo systemctl start postgresql.service

Alibaba Cloud Linux 2/CentOS 7

  1. 安裝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
  2. postgres使用者的家目錄下建立.pgpass檔案,用於自動提供PostgreSQL使用者的密碼。

    1. 切換到postgres使用者。

      sudo su - postgres
    2. 建立並配置.pgpass檔案。

      echo "192.168.1.10:5432:replication:replica_user:YOUR_SECURE_PASSWORD" > ~/.pgpass
      chmod 600 ~/.pgpass
    3. 退出postgres使用者。

      exit
  3. 從主節點複製資料。使用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使用者名稱。

  4. 建立standby.signal檔案以啟用備庫模式。此空檔案用於告知PostgreSQL在啟動時進入備用(standby)模式,而非作為主庫啟動。

    sudo -u postgres touch /var/lib/pgsql/15/data/standby.signal
  5. 配置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
  6. 啟動從節點服務。

    sudo systemctl enable postgresql-15.service
    sudo systemctl start postgresql-15.service

步驟四:驗證主從複製狀態

  1. 檢查複製相關進程。

    主從節點上負責資料同步的walsenderwalreceiver進程已啟動,表明複製串連已建立。

    • 在主節點上,檢查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

  2. 執行資料同步測試。

    在主節點寫入資料,然後在從節點驗證資料是否同步,以確認複製鏈路正常。

    • 在主節點上建立一個測試表並插入資料。

      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;"

      如果能查詢到已插入的資料,則表示主從複製已成功建立。