
PostgreSQL Streaming Replication(流式复制)可让您通过 WAL(预写日志)流,将数据从主节点(Master)持续复制到一台或多台备用节点(Replica)。本指南将带您在两台 Ubuntu VPS 上完成完整的主从配置,实现高可用性并将读取查询分流到备节点。
流式复制的工作原理
PostgreSQL 在将每次变更写入数据文件之前,会先记录到 WAL 中。流式复制以近实时的方式将这些 WAL 记录推送到备节点,使其保持"热备(Hot Standby)"状态 — 随时可响应只读查询。
- 主节点(Master) — 接受所有读写操作,并将 WAL 流式传输给备节点
- 备节点(Replica) — 应用接收到的 WAL,提供只读查询服务
- 复制延迟(Replication Lag) — 在网络条件良好的情况下,通常低于 1 秒
注意:默认情况下,PostgreSQL 流式复制为异步模式 — 主节点上已提交的事务可能未立即到达备节点。如需同步复制,请设置 synchronous_commit = on 并配置 synchronous_standby_names。
前置要求
- 两台 Ubuntu 22.04 VPS(主节点 IP:10.0.0.1,备节点 IP:10.0.0.2)
- 两台服务器上安装完全相同版本的 PostgreSQL 15 或 16
- 两台实例之间网络互通
- 两台服务器均具有 root 或 sudo 权限
第一步:在两台服务器上安装 PostgreSQL
# 在主节点和备节点上均执行
sudo apt update
sudo apt install -y postgresql postgresql-contrib
# 验证版本
psql --version
# 启用并启动服务
sudo systemctl enable postgresql
sudo systemctl start postgresql
第二步:配置主节点(Master)
编辑主节点的 postgresql.conf
sudo nano /etc/postgresql/15/main/postgresql.conf
添加或更新以下配置项:
listen_addresses = '*'
wal_level = replica
max_wal_senders = 5
wal_keep_size = 256MB
hot_standby = on
编辑主节点的 pg_hba.conf
sudo nano /etc/postgresql/15/main/pg_hba.conf
追加以下行(将 10.0.0.2 替换为您备节点的实际 IP):
host replication replicator 10.0.0.2/32 scram-sha-256
创建复制用户
sudo -u postgres psql
CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'StrongPass123!';
\q
重启主节点 PostgreSQL
sudo systemctl restart postgresql
第三步:配置备节点(Replica)
停止 PostgreSQL 并清空数据目录
sudo systemctl stop postgresql
sudo rm -rf /var/lib/postgresql/15/main/*
从主节点获取基础备份
# 在备节点上执行(将 10.0.0.1 替换为主节点 IP)
sudo -u postgres pg_basebackup \
-h 10.0.0.1 \
-U replicator \
-D /var/lib/postgresql/15/main \
-P -Xs -R
# -P = 显示进度
# -Xs = 备份期间同步流式传输 WAL
# -R = 自动写入 standby.signal 及恢复配置
提示输入密码时,请输入 StrongPass123!。
验证生成的文件
# 确认 standby.signal 已存在
ls /var/lib/postgresql/15/main/standby.signal
# 检查 postgresql.auto.conf 中的 primary_conninfo
sudo cat /var/lib/postgresql/15/main/postgresql.auto.conf
启动备节点 PostgreSQL
sudo systemctl start postgresql
sudo systemctl status postgresql
验证复制状态
在主节点上检查
sudo -u postgres psql -c "SELECT * FROM pg_stat_replication;"
正常运行时,结果中会出现一行,其中 state = streaming,且 sent_lsn 与 replay_lsn 的值非常接近。
在备节点上检查
sudo -u postgres psql -c "SELECT * FROM pg_stat_wal_receiver;"
快速冒烟测试
# Create a table on Master
sudo -u postgres psql
CREATE TABLE test_rep (id serial, msg text);
INSERT INTO test_rep (msg) VALUES ('Hello from Master');
\q
# Verify on Replica
sudo -u postgres psql
SELECT * FROM test_rep;
\q
监控延迟:在备节点上执行 SELECT now() - pg_last_xact_replay_timestamp() AS lag;,可测量复制延迟(以秒为单位)。延迟过高通常意味着网络存在瓶颈,或备节点的读取负载过重。
将读取查询路由到备节点
在应用程序中,将读取查询指向备节点的 IP 地址,以减轻主节点的负担。以下是 PHP 示例:
// Write connection → Master
$dbWrite = new PDO('pgsql:host=10.0.0.1;dbname=myapp', 'appuser', 'pass');
// Read connection → Replica
$dbRead = new PDO('pgsql:host=10.0.0.2;dbname=myapp', 'appuser', 'pass');
切勿向备节点发送写入查询 — 备节点处于只读模式,写入操作将返回错误。
主节点宕机时的故障切换
当主节点无法访问时,只需一条命令即可将备节点提升为新的主节点:
# Promote the Replica to Primary (run on the Replica)
sudo -u postgres pg_ctl promote -D /var/lib/postgresql/15/main
# Confirm it is now the Primary
sudo -u postgres psql -c "SELECT pg_is_in_recovery();"
# Expected result: f (false = it is now a Primary)
提升完成后,请将所有应用程序的连接字符串更新为新主节点的 IP 地址。如需将旧主节点重新加入集群,可将其重新部署为新主节点的备节点。
自动故障切换:对于需要自动故障切换的生产环境,Patroni 或 repmgr 等工具可自动处理领导者选举和提升流程,无需人工干预,从而将停机时间降到最低。
PostgreSQL 复制模式对比
PostgreSQL 支持多种复制模式,各模式适用于不同的需求场景。
| 模式 | 工作方式 | 优势 | 适用场景 |
|---|---|---|---|
| 流式复制(异步) | WAL 无需等待备节点确认即可发送 | 高吞吐量,主节点延迟低 | 通用读取扩展 |
| 流式复制(同步) | 主节点等待备节点确认 WAL 后再提交 | 零数据丢失(RPO = 0) | 金融系统、关键数据 |
| 逻辑复制 | 仅复制指定的表或数据库 | 灵活,支持不同 PostgreSQL 版本 | 跨版本迁移 |
| 级联复制 | 备节点将 WAL 转发给下游备节点 | 减少主节点的 WAL sender 负担 | 多区域副本扇出 |
WAL 归档与时间点恢复
复制并不等于备份。如果在主节点上误删数据,该操作会立即同步到备节点。WAL 归档可在复制的基础上实现时间点恢复(PITR)。
# Add to postgresql.conf on the Primary to enable WAL archiving
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/wal-archive/%f'
启用 WAL 归档后,您可以将数据库恢复到任意时间点 — 例如,在误执行 DROP TABLE 之前的一分钟 — 只需在 postgresql.auto.conf 中指定 recovery_target_time 即可。
- 在执行其他任何步骤之前,先在主节点上配置 WAL 归档
- 每月至少测试一次从归档完整恢复的流程
- 保留至少 7 天的归档,以覆盖恢复窗口期
- 可考虑使用 pgBackRest 或 Barman 自动管理备份生命周期
常见复制问题与解决方法
以下是首次配置流式复制时最常遇到的问题。
备节点无法连接主节点
请检查主节点的 pg_hba.conf 中是否包含备节点 IP 及正确的认证方式,同时确认两台服务器之间的防火墙已开放 5432 端口。
# Test connectivity from the Replica to the Primary
psql -h 10.0.0.1 -U replicator -d postgres
复制延迟持续增大
延迟过高通常是由网络瓶颈或备节点读取负载过重造成的。可在主节点上测量延迟:
SELECT client_addr, state,
pg_wal_lsn_diff(sent_lsn, replay_lsn) AS lag_bytes
FROM pg_stat_replication;
主节点因 WAL 积压导致磁盘空间不足
如果备节点长时间断线,WAL 文件会在主节点上大量堆积。请合理调整 wal_keep_size,或使用复制槽(Replication Slot)让主节点精确追踪备节点的消费进度。
生产环境建议:在正式依赖故障切换流程之前,务必在测试环境中演练一遍,并维护清晰的操作手册,以便团队在出现故障时能快速响应。
需要用于数据库的 VPS?
Linux VPS 每月仅需 500 泰铢起,配备完整 Root 权限、SSD 存储及 99% 在线率 — 完美支持 PostgreSQL、MySQL 及各类数据库工作负载。
查看 VPS 套餐