前面学完了理论知识,今天我们来实战学习下怎么配置这个流复制。为什么采用 docker 进行实验呢,原因很简单,非常方便。
#先设置目录
mkdir -p /data/postgres-replication
mkdir -p /data/postgres-replication/postgres-01
mkdir -p /data/postgres-replication/postgres-02
mkdir -p /data/postgres-replication/postgres-03
chmod 777 -R /data/postgres-replication/postgres-0*
vi /data/postgres-replication/docker-compose.yaml
version: '3.9'
services:
# 写节点
postgres-01:
container_name: postgres-01
hostname: postgres-01
image: timescale/timescaledb-ha:pg15-all
privileged: true
environment:
PGDATA: /home/postgres/db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- ./postgres-01:/home/postgres
ports:
- "5001:5432"
networks:
pg-net:
ipv4_address: 10.20.0.5
# 读节点一
postgres-02:
container_name: postgres-02
hostname: postgres-02
image: timescale/timescaledb-ha:pg15-all
privileged: true
environment:
PGDATA: /home/postgres/db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- ./postgres-02:/home/postgres
ports:
- "5002:5432"
networks:
pg-net:
ipv4_address: 10.20.0.6
# 读节点二
postgres-03:
container_name: postgres-03
hostname: postgres-03
image: timescale/timescaledb-ha:pg15-all
privileged: true
environment:
PGDATA: /home/postgres/db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- ./postgres-03:/home/postgres
ports:
- "5003:5432"
networks:
pg-net:
ipv4_address: 10.20.0.7
networks:
pg-net:
ipam:
config:
- subnet: 10.20.0.0/16
接着启动容器:docker-compose up -d
先进入到主节点进行配置 docker exec -it postgres-01 /bin/bash
#进入容器内的/home/postgres/pgdata/data目录,修改 pg_hba.conf,在最下方新增:
host replication all 0.0.0.0/0 md5
接着配置 postgresql.conf(这些配置项默认是配置好的),检查一下就行
#设置以下
listen_addresses = '*' # 允许远程连接
hot_standby = on # 打开热备
wal_level = replica # 设置 WAL 日志级别为 replica
max_wal_senders = 3 # 允许的 WAL 发送者数量,根据需要进行调整
创建流复制的账号
postgres=# create role replica with login replication encrypted password 'replica';
然后重启下postgres-01 容器,使配置生效 docker-compose restart postgres-01
到此主节点就配置好了,接下来我们来配置从节点
这个时候我们需要进入 postgres-02 的容器内:docker exec -it postgres-02 sh,同步主节点的数据。
su postgres
pg_basebackup -Fp --progress -D /home/postgres/pgdata/data -R -h 10.20.0.5 -p 5432 -U replica --password
执行成功后可以在备库的数据目录下看到复制过来的文件和配置文件
因为使用了 -R 参数,也会生成 standby.signal 文件,同时在 postgresql.auto.conf 中生成如下内容
[root@192 data]# ls
PG_VERSION base pg_dynshmem pg_logical pg_replslot pg_stat pg_tblspc pg_xact postmaster.opts
backup_label.old global pg_hba.conf pg_multixact pg_serial pg_stat_tmp pg_twophase postgresql.auto.conf postmaster.pid
backup_manifest pg_commit_ts pg_ident.conf pg_notify pg_snapshots pg_subtrans pg_wal postgresql.conf standby.signal
[root@192 data]# cat postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=replica password=replica channel_binding=prefer host=10.20.0.5 port=5432 sslmode=prefer sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
[root@192 data]#
因为我们一开始配置 postgres-02 的 PGDATA 为/home/postgres/db,我们需要修改这个同步过来的目录,然后重启。
将docker-compose.yaml 文件下的 postgres-02 的
PGDATA: /home/postgres/db 修改成 /home/postgres/pgdata/data
然后重启docker-compose restart postgres-02
postgres-03 也是重复该操作。
在主节点的 psql 中执行:SELECT * FROM pg_stat_replication;如下图所示,到此我们的同步搭建就成功了。
postgres=# SELECT * FROM pg_stat_replication;
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state | reply_time
-----+----------+---------+------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+-----------+-----------+-----------+------------+-----------+-----------+------------+---------------+------------+-------------------------------
38 | 16387 | replica | walreceiver | 10.20.0.7 | | 42382 | 2025-07-06 08:14:59.685966+00 | | streaming | 0/70001F8 | 0/70001F8 | 0/70001F8 | 0/70001F8 | | | | 0 | async | 2025-07-06 08:40:44.867142+00
39 | 16387 | replica | walreceiver | 10.20.0.6 | | 47500 | 2025-07-06 08:14:59.722339+00 | | streaming | 0/70001F8 | 0/70001F8 | 0/70001F8 | 0/70001F8 | | | | 0 | async | 2025-07-06 08:40:44.827293+00
(2 rows)
测试验证
#在postgres-01执行
create table test(id int);
insert into test values (1),(2),(3);
#在postgres-02查询数据是否有同步过来
postgres=# select * from test;
id
----
1
2
3
(3 rows)
评论