PostgreSQL 流复制配置教程

PostgreSQL 流复制(Streaming Replication)是 PostgreSQL 原生的物理复制方案,通过持续传输 WAL(Write-Ahead Log)日志实现主备数据同步。流复制可以用于读写分离、数据备份和高可用架构。本文将在搬瓦工 VPS 上完整演示 PostgreSQL 流复制的配置过程,包括异步复制和同步复制两种模式。

一、环境准备

  • 主库(Primary):192.168.1.10,PostgreSQL 16
  • 备库(Standby):192.168.1.20,PostgreSQL 16
  • 操作系统:Ubuntu 22.04

在两台服务器上安装 PostgreSQL 16:

# 添加 PostgreSQL 官方仓库
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt update

# 安装 PostgreSQL 16
apt install postgresql-16 -y
systemctl start postgresql
systemctl enable postgresql

二、配置主库

2.1 创建复制用户

su - postgres
psql

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'ReplPass123!';
\q

2.2 修改 postgresql.conf

编辑 /etc/postgresql/16/main/postgresql.conf

listen_addresses = '*'
wal_level = replica
max_wal_senders = 5
wal_keep_size = 1024
max_replication_slots = 5
hot_standby = on
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/16/archive/%f'

参数说明:wal_level = replica 是流复制的最低级别;max_wal_senders 允许最多 5 个备库连接;wal_keep_size 保留 1GB WAL 防止备库落后太多被清理。

2.3 配置 pg_hba.conf

编辑 /etc/postgresql/16/main/pg_hba.conf,添加复制权限:

# 允许备库使用 replicator 账号进行流复制
host    replication     replicator      192.168.1.20/32         scram-sha-256

2.4 创建复制槽和归档目录

# 创建归档目录
mkdir -p /var/lib/postgresql/16/archive
chown postgres:postgres /var/lib/postgresql/16/archive

# 重启主库
systemctl restart postgresql

# 创建复制槽(防止 WAL 被过早清理)
su - postgres
psql -c "SELECT pg_create_physical_replication_slot('standby_slot');"

三、配置备库

3.1 停止备库并清空数据

systemctl stop postgresql
rm -rf /var/lib/postgresql/16/main/*

3.2 使用 pg_basebackup 同步数据

su - postgres
pg_basebackup -h 192.168.1.10 -U replicator -D /var/lib/postgresql/16/main -Fp -Xs -P -R -S standby_slot

参数说明:

  • -Fp:以 plain 格式输出。
  • -Xs:使用流方式传输 WAL。
  • -P:显示进度。
  • -R:自动创建 standby.signal 文件和连接信息,这是关键参数。
  • -S standby_slot:使用之前创建的复制槽。

3.3 验证备库配置文件

pg_basebackup -R 会自动在数据目录下创建 standby.signal 文件,并在 postgresql.auto.conf 中写入连接信息:

cat /var/lib/postgresql/16/main/postgresql.auto.conf

应包含类似内容:

primary_conninfo = 'user=replicator password=ReplPass123! host=192.168.1.10 port=5432 sslmode=prefer'
primary_slot_name = 'standby_slot'

3.4 启动备库

systemctl start postgresql

四、验证复制状态

4.1 在主库查看复制状态

su - postgres
psql -c "SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;"

正常情况下可以看到备库的连接信息,state 为 streaming。

4.2 在备库验证

psql -c "SELECT pg_is_in_recovery();"

返回 t 表示当前是备库模式。

4.3 测试数据同步

# 在主库创建测试数据
psql -c "CREATE TABLE test_repl (id serial, msg text); INSERT INTO test_repl (msg) VALUES ('hello from primary');"

# 在备库查询
psql -c "SELECT * FROM test_repl;"

五、同步复制配置

默认的异步复制存在数据丢失风险。同步复制确保事务在至少一个备库确认写入后才提交。

5.1 备库设置 application_name

在备库的 postgresql.auto.conf 中添加 application_name:

primary_conninfo = 'user=replicator password=ReplPass123! host=192.168.1.10 port=5432 application_name=standby1'

5.2 主库开启同步复制

在主库 postgresql.conf 中设置:

synchronous_standby_names = 'FIRST 1 (standby1)'
synchronous_commit = on

重启两端后,在主库验证:

psql -c "SELECT application_name, sync_state FROM pg_stat_replication;"

sync_state 显示 sync 即为同步复制模式。

六、监控复制延迟

# 在主库查看每个备库的延迟
SELECT client_addr, application_name,
       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS replay_lag_bytes,
       replay_lag
FROM pg_stat_replication;

# 在备库查看自身延迟
SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay;

七、故障切换(Failover)

当主库故障时,需要将备库提升为新主库。

7.1 手动故障切换

# 在备库执行提升命令
su - postgres
pg_ctl promote -D /var/lib/postgresql/16/main

# 或使用 pg_promote() 函数
psql -c "SELECT pg_promote();"

提升后 standby.signal 文件会被自动删除,备库变为可读写的主库。

7.2 使用 Patroni 实现自动故障切换

生产环境建议使用 Patroni 配合 etcd 实现自动化的高可用管理。安装 Patroni:

apt install python3-pip -y
pip3 install patroni[etcd] psycopg2-binary

Patroni 可以自动监控主备状态、执行故障切换,并提供 REST API 用于健康检查和管理。

八、常见问题

  • 备库无法连接主库:检查 pg_hba.conf 是否允许 replication 连接,防火墙 5432 端口是否开放。
  • WAL 被清理导致备库落后:使用复制槽或增大 wal_keep_size,复制槽会阻止 WAL 清理直到备库消费。
  • 同步复制导致主库卡住:当备库不可用时同步模式会阻塞主库事务。可以设置 synchronous_commit = remote_apply 或使用多个同步备库。
  • 备库 timeline 不匹配:主库发生过 failover 后 timeline 变化,需要使用 pg_rewind 或重做 basebackup。

总结

PostgreSQL 流复制是构建高可用数据库架构的核心技术。通过本文的配置,你可以在搬瓦工 VPS 上实现主备实时同步和读写分离。配合 PgBouncer 连接池 可以进一步优化性能。选购搬瓦工 VPS 请查看 全部方案,使用优惠码 NODESEEK2026 享受 6.77% 折扣,通过 bwh81.net 进入官网购买。

关于本站

搬瓦工VPS中文网(bwgvps.com)是非官方中文信息站,整理搬瓦工的方案、优惠和教程。我们不销售主机,不提供技术服务。

新手必读
搬瓦工优惠码

NODESEEK2026(优惠 6.77%)

购买时填入即可抵扣。