全部产品
Search
文档中心

云服务器 ECS:搭建PostgreSQL主从架构

更新时间:Dec 26, 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位。

  • 网络:专有网络VPC,位于同一地域和可用区,以降低网络延迟,确保数据同步性能。需开通公网访问权限,用于下载安装包。

    高可用性主要通过主从架构实现,从节点作为数据副本用于故障恢复。
  • 安全组:配置相同的安全组。

示例私网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;"

      如果能查询到已插入的数据,则表示主从复制已成功建立。