PostgreSQL:详解如何搭建流复制集群

文章目录

    • 一、前置知识
      • [1.1 流复制原理](#1.1 流复制原理)
      • [1.2 架构说明](#1.2 架构说明)
    • 二、环境准备
      • [2.1 系统要求](#2.1 系统要求)
      • [2.2 节点信息示例](#2.2 节点信息示例)
    • [三、安装 PostgreSQL](#三、安装 PostgreSQL)
    • 四、配置主节点(Primary)
      • [4.1 修改 postgresql.conf](#4.1 修改 postgresql.conf)
      • [4.2 配置 pg_hba.conf](#4.2 配置 pg_hba.conf)
      • [4.3 创建复制用户](#4.3 创建复制用户)
      • [4.4 重启主库](#4.4 重启主库)
    • 五、配置备节点(Standby)
      • [5.1 清理原有数据目录(如有)](#5.1 清理原有数据目录(如有))
      • [5.2 使用 pg_basebackup 初始化备库](#5.2 使用 pg_basebackup 初始化备库)
      • [5.3 验证生成的文件](#5.3 验证生成的文件)
      • [5.4 启动备库](#5.4 启动备库)
    • 六、验证流复制状态
      • [6.1 在主库查看复制状态](#6.1 在主库查看复制状态)
      • [6.2 在备库查看是否只读](#6.2 在备库查看是否只读)
      • [6.3 检查延迟](#6.3 检查延迟)
    • 七、高级配置(可选)
      • [7.1 使用复制槽(Replication Slot)](#7.1 使用复制槽(Replication Slot))
      • [7.2 同步复制](#7.2 同步复制)
      • [7.3 归档与 PITR(时间点恢复)](#7.3 归档与 PITR(时间点恢复))
    • 八、故障处理与切换
      • [8.1 主库宕机:手动提升备库](#8.1 主库宕机:手动提升备库)
      • [8.2 原主库恢复后重新加入(作为新备库)](#8.2 原主库恢复后重新加入(作为新备库))
    • 九、监控与维护

搭建 PostgreSQL 流复制(Streaming Replication)集群是实现高可用、读写分离和灾难恢复的关键技术之一。流复制基于主从架构,主节点(Primary)将 WAL(Write-Ahead Logging)日志实时传输到一个或多个备节点(Standby),备节点重放这些日志以保持与主节点的数据同步。


一、前置知识

1.1 流复制原理

  • PostgreSQL 使用 WAL 日志记录所有数据变更。
  • 主库将 WAL 日志通过网络实时发送给备库(物理复制)。
  • 备库以只读模式运行,可提供查询服务(Hot Standby)。
  • 支持同步复制(synchronous_commit = on)和异步复制(默认)。

1.2 架构说明

  • 主节点(Primary):接受写操作,生成 WAL。
  • 备节点(Standby):接收并应用 WAL,只读。
  • 可扩展为一主多从架构。
  • 配合 pg_rewind、repmgr 或 Patroni 可实现自动故障切换(本篇聚焦基础流复制,不涉及 HA 工具)。

二、环境准备

2.1 系统要求

  • 操作系统:Linux(如 CentOS 7/8、Ubuntu 20.04+)
  • PostgreSQL 版本:建议 12+(本文以 14 为例)
  • 主备节点时间同步(NTP)
  • 主备节点网络互通(开放 PostgreSQL 端口,默认 5432)

2.2 节点信息示例

角色 主机名 IP 地址 数据目录
Primary pg-primary 192.168.1.10 /var/lib/pgsql/14/data
- Standby pg-standby 192.168.1.11 /var/lib/pgsql/14/data

注意:主备节点 PostgreSQL 版本必须一致。


三、安装 PostgreSQL

在主备节点上分别安装相同版本的 PostgreSQL。

以 CentOS 为例:

bash 复制代码
# 添加官方仓库
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# 安装 PostgreSQL 14
sudo yum install -y postgresql14-server postgresql14-contrib

# 初始化数据库(仅在主节点执行一次)
sudo /usr/pgsql-14/bin/postgresql-14-setup initdb

Ubuntu 用户可使用 apt 安装,流程类似。


四、配置主节点(Primary)

4.1 修改 postgresql.conf

编辑 /var/lib/pgsql/14/data/postgresql.conf

conf 复制代码
# 监听地址(允许远程连接)
listen_addresses = '*'

# WAL 相关设置
wal_level = replica                # 必须为 replica 或 logical
max_wal_senders = 10               # 允许的最大 WAL 发送进程数
wal_keep_size = 1GB                # 保留的 WAL 文件大小(PostgreSQL 13+)
# 对于旧版本(<13),使用 wal_keep_segments = 32

# 启用 Hot Standby 支持(虽在主库设置,但影响备库行为)
hot_standby = on

# 可选:启用同步复制(需配合 synchronous_standby_names)
# synchronous_commit = on
# synchronous_standby_names = 'pg-standby'

4.2 配置 pg_hba.conf

编辑 /var/lib/pgsql/14/data/pg_hba.conf,添加复制用户访问权限:

conf 复制代码
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    replication     repuser         192.168.1.11/32         md5
host    all             all             0.0.0.0/0               md5   # 根据安全策略调整

replication 是一个虚拟数据库名,专用于流复制连接。

4.3 创建复制用户

登录主库,创建专用复制用户:

sql 复制代码
CREATE USER repuser WITH REPLICATION ENCRYPTED PASSWORD 'StrongPass123!';

4.4 重启主库

bash 复制代码
sudo systemctl restart postgresql-14

验证监听状态:

bash 复制代码
ss -tulnp | grep 5432

五、配置备节点(Standby)

5.1 清理原有数据目录(如有)

bash 复制代码
sudo systemctl stop postgresql-14
sudo rm -rf /var/lib/pgsql/14/data/*

5.2 使用 pg_basebackup 初始化备库

从主库拉取基础备份:

bash 复制代码
sudo -u postgres pg_basebackup \
  -h 192.168.1.10 \
  -U repuser \
  -D /var/lib/pgsql/14/data \
  -P \
  -v \
  -R \
  -X stream \
  -C \
  -S standby_slot_1

参数说明:

  • -h:主库 IP
  • -U:复制用户
  • -D:目标数据目录
  • -P:显示进度
  • -v:详细输出
  • -R:自动生成 recovery.conf(PG 12+ 会生成 standby.signal 和 postgresql.auto.conf)
  • -X stream:以流方式传输 WAL
  • -C:在主库创建复制槽(replication slot)
  • -S:指定复制槽名称(可选)

注意:PostgreSQL 12 起不再使用 recovery.conf,而是使用 standby.signal 文件和 postgresql.auto.conf 中的 primary_conninfo

5.3 验证生成的文件

执行后,应看到:

  • /var/lib/pgsql/14/data/standby.signal(空文件,标识为备库)
  • postgresql.auto.conf 中包含 primary_conninfo = '...'

若未自动生成,可手动创建:

bash 复制代码
# 创建 standby.signal
sudo -u postgres touch /var/lib/pgsql/14/data/standby.signal

# 编辑 postgresql.auto.conf(或直接在 postgresql.conf 中添加)
primary_conninfo = 'host=192.168.1.10 port=5432 user=repuser password=StrongPass123! application_name=pg-standby'

5.4 启动备库

bash 复制代码
sudo systemctl start postgresql-14

六、验证流复制状态

6.1 在主库查看复制状态

sql 复制代码
SELECT * FROM pg_stat_replication;

关键字段:

  • application_name:应为 pg-standby
  • state:应为 streaming
  • sync_state:异步为 async,同步为 sync

6.2 在备库查看是否只读

sql 复制代码
SHOW hot_standby;  -- 应为 on
SELECT pg_is_in_recovery();  -- 应返回 true

尝试写入应报错:

sql 复制代码
INSERT INTO test VALUES (1);  -- ERROR: cannot execute INSERT in a read-only transaction

6.3 检查延迟

主库执行:

sql 复制代码
SELECT 
  application_name,
  pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS bytes_lag
FROM pg_stat_replication;

bytes_lag 接近 0,说明同步良好。


七、高级配置(可选)

7.1 使用复制槽(Replication Slot)

复制槽可防止主库过早清理 WAL,避免备库因断连导致无法追平。

已在 pg_basebackup -C -S 中创建。也可手动创建:

sql 复制代码
-- 在主库执行
SELECT * FROM pg_create_physical_replication_slot('standby_slot_1');

并在备库 primary_conninfo 中添加:

conf 复制代码
primary_conninfo = '... slot=standby_slot_1'

7.2 同步复制

若需强一致性,配置同步复制:

主库 postgresql.conf

conf 复制代码
synchronous_commit = on
synchronous_standby_names = 'FIRST 1 (pg-standby)'

重启主库。此时主库事务需等待至少一个同步备库确认后才提交。

7.3 归档与 PITR(时间点恢复)

可结合 WAL 归档实现更完整的备份策略:

conf 复制代码
# postgresql.conf
archive_mode = on
archive_command = 'cp %p /path/to/archive/%f'

八、故障处理与切换

8.1 主库宕机:手动提升备库

在备库执行:

bash 复制代码
sudo -u postgres pg_ctl promote -D /var/lib/pgsql/14/data

或创建 promote.trigger 文件(PG 12+):

bash 复制代码
sudo -u postgres touch /var/lib/pgsql/14/data/promote.trigger

备库将变为新主库。

8.2 原主库恢复后重新加入(作为新备库)

原主库需重建数据目录(或使用 pg_rewind):

bash 复制代码
# 停止原主库
sudo systemctl stop postgresql-14

# 使用 pg_rewind(需在原主库配置中启用 wal_log_hints=on 或 data checksums)
pg_rewind \
  --target-pgdata=/var/lib/pgsql/14/data \
  --source-server='host=192.168.1.11 port=5432 user=repuser password=StrongPass123!'

# 清理旧配置,创建 standby.signal
rm -f /var/lib/pgsql/14/data/postmaster.pid
touch /var/lib/pgsql/14/data/standby.signal

# 启动
sudo systemctl start postgresql-14

若未启用 checksums 或 wal_log_hints,则只能通过 pg_basebackup 重新初始化。


九、监控与维护

  • 定期检查 pg_stat_replication 延迟
  • 监控磁盘空间(WAL 积累可能导致主库磁盘满)
  • 使用 pg_controldata 查看数据库状态
  • 设置日志归档和定期逻辑备份(pg_dump)

总结:PostgreSQL 流复制搭建核心步骤:

  1. 主库配置 WAL 和复制权限;
  2. 创建复制用户;
  3. 使用 pg_basebackup 初始化备库;
  4. 启动备库并验证同步状态。

虽然流复制本身不提供自动故障转移,但它是构建高可用架构的基础。生产环境中建议结合 Patroni + etcd/ZooKeeper 或 repmgr 实现自动化管理。


注意事项:

  • 主备 OS、PostgreSQL 版本、编译选项必须一致;
  • 时间必须同步(NTP);
  • 网络稳定性和带宽影响复制性能;
  • 避免在备库执行 DDL(即使只读,某些操作可能阻塞 WAL 应用)。

通过以上步骤,即可成功搭建一个稳定可靠的 PostgreSQL 流复制集群。

相关推荐
小高不会迪斯科8 小时前
CMU 15445学习心得(二) 内存管理及数据移动--数据库系统如何玩转内存
数据库·oracle
e***8909 小时前
MySQL 8.0版本JDBC驱动Jar包
数据库·mysql·jar
l1t9 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
失忆爆表症10 小时前
03_数据库配置指南:PostgreSQL 17 + pgvector 向量存储
数据库·postgresql
AI_567810 小时前
Excel数据透视表提速:Power Query预处理百万数据
数据库·excel
SQL必知必会11 小时前
SQL 窗口帧:ROWS vs RANGE 深度解析
数据库·sql·性能优化
Gauss松鼠会11 小时前
【GaussDB】GaussDB数据库开发设计之JDBC高可用性
数据库·数据库开发·gaussdb
+VX:Fegn089512 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
识君啊12 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端
一个天蝎座 白勺 程序猿13 小时前
破译JSON密码:KingbaseES全场景JSON数据处理实战指南
数据库·sql·json·kingbasees·金仓数据库