文章目录
-
- 一、前置知识
-
- [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-standbystate:应为streamingsync_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 流复制搭建核心步骤:
- 主库配置 WAL 和复制权限;
- 创建复制用户;
- 使用
pg_basebackup初始化备库; - 启动备库并验证同步状态。
虽然流复制本身不提供自动故障转移,但它是构建高可用架构的基础。生产环境中建议结合 Patroni + etcd/ZooKeeper 或 repmgr 实现自动化管理。
注意事项:
- 主备 OS、PostgreSQL 版本、编译选项必须一致;
- 时间必须同步(NTP);
- 网络稳定性和带宽影响复制性能;
- 避免在备库执行 DDL(即使只读,某些操作可能阻塞 WAL 应用)。
通过以上步骤,即可成功搭建一个稳定可靠的 PostgreSQL 流复制集群。