postgrresql 搭建简单流复制主从
主库配置:
创建复制用户:登录主库数据库,创建一个专门用于复制的用户(如果还未创建)。
sql
CREATE USER replica WITH REPLICATION ENCRYPTED PASSWORD 'replica';
修改 pg_hba.conf:编辑主库的数据目录下的 pg_hba.conf 文件,允许备库(偶数机)使用复制用户连接。在文件中添加如下行(假设偶数机IP为 192.168.1.102):
host replication replica 192.168.81.0/24 trust
方式 1:仅允许 192.168.81.129 这个 IP 的复制连接(推荐)
# 格式:host replication 用户名 客户端IP/掩码 认证方式
host replication postgres 192.168.81.129/32 md5 # 或 trust(测试环境)
方式 2:允许整个 192.168.81.0/24 网段的复制连接(适合集群环境)
host replication postgres 192.168.81.0/24 md5
/usr/local/pg12/bin/pg_ctl -D /usr/local/pg12/data reload
修改 postgresql.conf:修改主库的 postgresql.conf 文件,开启必要的复制参数。
listen_addresses = '*' # 监听所有地址,或指定偶数机IP
wal_level = replica # 设置为 replica 或更高,以支持流复制
max_wal_senders = 10 # 最大 WAL 发送进程数,至少为1
wal_keep_size = 1GB # (或 wal_keep_segments)保留的 WAL 日志大小,防止备库落后太多
hot_standby=on
重启主库服务:使配置生效。
/usr/local/pg12/bin/pg_ctl -D /usr/local/pg12/data stop
/usr/local/pg12/bin/pg_ctl -D /usr/local/pg12/data start
从库配置
停止备库服务并清空数据目录:确保备库服务停止,并清空其数据目录($PGDATA),以便从主库拉取基础备份。
/usr/local/pg12/bin/pg_ctl -D /usr/local/pg12/data stop
rm -rf /usr/local/pg12/data/* # 请替换为你的实际数据目录路径 */
从主库拉取基础备份:使用 pg_basebackup 工具从主库复制整个数据集群到备库
pg_basebackup -h 192.168.1.101 -U replica -p 5432 -D /var/lib/pgsql/16/data -Fp -Xs -P -R
-D: 备库本地数据目录
-Xs: 使用流复制模式备份最新WAL
-R: 关键参数,会在备份后自动创建 standby.signal 文件,并将主库连接信息写入 postgresql.auto.conf,告知备库如何连接主库 。
eg:primary_conninfo = 'user=replica host=192.168.81.128 port=1536 sslmode=disable sslcompression=1'
启动备库:启动备库服务,它将成为基数机的异步流复制备库。
/usr/local/pg12/bin/pg_ctl -D /usr/local/pg12/data start
验证异步同步状态
postgres=# SELECT client_addr, state, sync_state FROM pg_stat_replication;
client_addr | state | sync_state
----------------+-----------+------------
192.168.81.129 | streaming | async
你应该能看到偶数机的IP地址,且 sync_state 列显示为 async,表示异步复制正常运行 。
创建新数据库 newdb1 并验证:
-- 在主库执行
CREATE DATABASE newdb1;
如果一切正常,你应该能在备库的数据库列表中看到刚刚在主库创建的 newdb1。这表明数据已通过流复制成功同步
主从切换:
此步骤模拟主库故障或计划内维护,我们将偶数机提升为新的主库。
执行切换
将原基数机(旧主库)降级为备库:
优雅关闭旧主库:
# 在旧主库(基数机)执行,使用 fast 模式快速关闭
pg_ctl -D /var/lib/pgsql/16/data stop -m fast
# 或 systemctl stop postgresql
将原偶数机(旧备库)提升为新主库:
# 在新主库(偶数机)执行提升命令
/usr/local/pg12/bin/pg_ctl -D /usr/local/pg12/data promote
# 或 systemctl promote postgresql@16-main (取决于系统)
# 或创建一个触发器文件 (如果配置了 promote_trigger_file)
SELECT client_addr, state, sync_state FROM pg_stat_replication;
重新配置复制方向(可选但推荐,以便新主库有备库)
同步时间线
注意要使用用户postgres,否者会报错执行读取二进制文件权限不足
pg_rewind --target-pgdata=/usr/local/pg12/data/ --source-server="user=postgres password=postgres host=192.168.81.12 port=1536"
为了让新的主库(原偶数机)拥有一个新的备库(原基数机),我们需要在旧主库上重新配置,使其指向新主库。
在旧主库(基数机):
确保其数据目录是干净的或重新拉取基础备份(如果数据不重要,可直接复用现有数据,但需确保与新主库一致)。
编辑或确认 postgresql.auto.conf 文件(或在 postgresql.conf 中)包含指向新主库的连接信息
vim postgresql.auto.conf
primary_conninfo = 'host=192.168.1.102 port=5432 user=replica password=your_strong_password application_name=standby1'
primary_conninfo = 'user=replica host=192.168.81.129 port=1536 sslmode=disable sslcompression=1'
在数据目录中创建 standby.signal 文件,告诉 PostgreSQL 以备库模式启动。(空目录)
touch /usr/local/pg12/data/standby.signal
启动旧主库服务,它现在会作为新主库(偶数机)的备库开始运行。
/usr/local/pg12/bin/pg_ctl -D /usr/local/pg12/data start
验证新主库上的操作是否同步
在新的主库(原偶数机)创建数据库 newdb2:
-- 在新的主库(偶数机)执行
CREATE DATABASE newdb2;
pg_stat_replication 表的状态说明
状态总览与速查
状态流转路径解析
在典型的流复制场景中,状态会沿着清晰的路径变化:
- 流复制启动:startup → catchup → streaming。备库重启或初始建立连接时会经过这些阶段,快速追平数据后进入 streaming 稳态。
- 执行在线备份 (pg_basebackup):startup → backup → streaming → stopping。备份开始时进入 backup 状态,为保持一致性可能短暂切换到 streaming,完成后进入 stopping。
- 备库数据落后:当已处于 streaming 状态的备库因网络或负载等原因落后主库时,会切回 catchup 状态追赶数据,追平后再自动恢复为 streaming。
state 字段描述了WAL发送进程的状态,而 sync_state 字段则标识了同步方式(异步 async、同步 sync、潜在 potential 等),两者共同描述了一个完整的复制连接状态。

浙公网安备 33010602011771号