PostgreSQL高可用架构Repmgr部署流程
节点规划
主机 | hostname | 角色 | 组件 |
---|---|---|---|
10.0.0.41 | repmgr01 | Leader | PostgreSQL 15.5、repmgr 5.5.0 |
10.0.0.42 | repmgr02 | standby1 | PostgreSQL 15.5、repmgr 5.5.0 |
10.0.0.43 | repmgr03 | standby2 | PostgreSQL 15.5、repmgr 5.5.0 |
1.系统准备
1.1 系统优化
请阅读 PostgreSQL部署前的系统准备
1.2 安装依赖
yum install -y yum-utils openjade docbook-dtds docbook-style-dsssl docbook-style-xsl
yum install -y cmake make gcc zlib gcc-c++ perl readline readline-devel zlib
yum install -y yum-builddep flex libselinux-devel libxml2-devel libxslt-devel openssl-devel pam-devel readline-devel libcurl-devel json-c-devel
2. 创建用户与互信
2.1 配置域名解析
#所有节点root用户下操作
cat >> /etc/hosts << EOF
10.0.0.41 repmgr01
10.0.0.42 repmgr02
10.0.0.43 repmgr03
EOF
2.2 创建用户与目录
#所有节点root用户下操作
groupadd -g 701 postgres
useradd -g 701 -u 701 -s /bin/bash -m postgres
passwd postgresmkdir /data/pgsql/{data,log} -p
mkdir /data/repmgr -p
chown -R postgres.postgres /data
2.3 配置互信
#所有节点都要与其它节点互信,postgres用户下操作
(1)生成公钥
su - postgres
rm -rf ~/.ssh
ssh-keygen -t rsa(2)将公钥分发到所有节点
for i in {1..3};do ssh-copy-id -i postgres@repmgr0$i;done
(3)互信验证
for i in {1..3};do ssh postgres@repmgr0$i hostname;done
3.软件安装
2.1 安装postgresql
#所有节点root用户下操作
(1)编译安装
[root@repmgr01 ~]# cd /opt
tar xf postgresql-15.5.tar.gz
cd postgresql-15.5
./configure --prefix=/usr/local/postgresql-15.5 --with-perl --with-python
make && make install(2)创建软连接,方便日后升级
[root@repmgr01 postgresql-15.5]# ln -sf /usr/local/postgresql-15.5 /usr/local/pgsql(3)安装contrib目录下的工具
[root@repmgr01 postgresql-15.5]# cd contrib/
[root@repmgr01 contrib]# make && make install(4)加入环境变量
[root@repmgr01 contrib]# vi /etc/profile
export PATH=/usr/local/pgsql/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql/lib:$LD_LIBRARY_PATH
export PGDATA=/data/pgsql/data
export PGHOST=/tmp[root@repmgr01 contrib]# source /etc/profile(5)验证安装
[root@repmgr01 contrib]# psql -V
psql (PostgreSQL) 15.5
2.2 安装repmgr
#所有节点root用户下操作
cd /opt
tar xf repmgr-5.5.0.tar.gz
cd repmgr-5.5.0
./configure #常规安装路径/usr/local/pgsql/bin/pg_config,如果不一致需要指定--with-pgconfig=/path/to/your/pg_config
make && make install[root@repmgr01 ~]# repmgr -V
repmgr 5.5.0
4.集群部署
4.1 配置 PostgreSQL 主节点
4.1.1 初始化主节点
[root@repmgr01 ~]# su - postgres
[postgres@repmgr01 ~]$ initdb -D $PGDATA
4.1.2 编辑配置文件
#篇幅原因只贴出一些必要参数,更多优化参数请自行了解
[postgres@repmgr01 ~]$ cd /data/pgsql/data/
[postgres@repmgr01 data]$ > postgresql.conf
cat >> postgresql.conf << EOF
shared_preload_libraries = 'repmgr'
############# Connection #############
listen_addresses = '*'
port = 5432
max_connections = 500
superuser_reserved_connections = 3
############# Buffer #############
shared_buffers = 2GB
temp_buffers = 8MB
work_mem = 4MB
############# Log #############
logging_collector = on
log_min_messages = warning
log_statement = ddl
log_directory = '/data/pgsql/log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_truncate_on_rotation = off
log_rotation_age = 1d
log_rotation_size = 0
############# Wal #############
wal_level = replica
wal_log_hints = on
wal_compression = on
max_wal_senders = 10
full_page_writes = on
synchronous_commit = on
wal_sync_method = fdatasync
max_wal_size = 40GB
min_wal_size = 10GB
fsync = on
############# VACUUM #############
autovacuum = on
autovacuum_max_workers = 10
############ 流复制 ##############
hot_standby=on
hot_standby_feedback=on
EOF
4.1.3 启动主节点
[postgres@repmgr01 data]$ pg_ctl start -D $PGDATA
4.1.4 创建管理用户
(1)修改超级用户密码
[postgres@repmgr01 data]$ psql
psql (15.5)
Type "help" for help.postgres=# alter user postgres password 'Postgres@123';(2)创建管理用户
create user repmgr with superuser password 'repmgr' connection limit 20;
create database repmgr owner repmgr;
alter user repmgr set search_path to repmgr, "$user", public;
4.1.5 修改 pg_hba.conf
[postgres@repmgr01 data]$ vim pg_hba.conf
# TYPE DATABASE USER ADDRESS METHODlocal all postgres scram-sha-256
# IPv4 local connections:
host all postgres 127.0.0.1/32 scram-sha-256
host all postgres 10.0.0.0/24 scram-sha-256
host all postgres ::1/128 scram-sha-256
host replication repmgr 10.0.0.0/24 trust
host repmgr repmgr 10.0.0.0/24 scram-sha-256
host repmgr repmgr 127.0.0.1/32 scram-sha-256
host repmgr repmgr ::1/128 scram-sha-256[postgres@repmgr01 data]$ pg_ctl reload
server signaled
4.1.5 配置用户免密登录
[postgres@repmgr01 data]$ vim ~/.pgpass
# hostname:port:database:username:password
localhost:5432:postgres:postgres:Postgres@123
10.0.0.41:5432:repmgr:repmgr:repmgr
10.0.0.42:5432:repmgr:repmgr:repmgr
10.0.0.43:5432:repmgr:repmgr:repmgr
127.0.0.1:5432:repmgr:repmgr:repmgr[postgres@repmgr01 data]$ chmod 600 ~/.pgpass
4.1.6 编辑repmgr配置文件
[postgres@repmgr01 data]$ vim /data/repmgr/repmgr.conf
####### cluster #######
node_id=1
node_name='node-01'
conninfo='host=10.0.0.41 port=5432 user=repmgr dbname=repmgr connect_timeout=2'
data_directory='/data/pgsql/data'####### failover #######
failover='automatic'
# 在主节点出现故障时,备用节点提升为新主节点所执行的命令
promote_command='/usr/local/pgsql/bin/repmgr standby promote --config-file=/data/repmgr/repmgr.conf --log-to-file'
# %n 是一个占位符,代表新主节点的 ID。告知备用节点新主节点的ID,以便它能准确地连接到新主节点并进行数据同步
follow_command='/usr/local/pgsql/bin/repmgr standby follow --config-file=/data/repmgr/repmgr.conf --log-to-file --upstream-node-id=%n'
primary_visibility_consensus=true
standby_disconnect_on_failover=true
use_replication_slots = true
monitoring_history=yes
connection_check_type=ping
reconnect_attempts=3
reconnect_interval=5service_start_command='pg_ctl start -D /data/pgsql/data'
service_stop_command='pg_ctl stop -D /data/pgsql/data'
repmgrd_service_start_command='/usr/local/pgsql/bin/repmgrd -f /data/repmgr/repmgr.conf start'
repmgrd_service_stop_command='kill -9 `cat /data/repmgr/repmgrd.pid`'####### log #######
log_level=INFO
log_file='/data/repmgr/repmgrd.log'
log_status_interval=10
4.1.7 注册主节点
repmgr -f /data/repmgr/repmgr.conf primary register
repmgr -f /data/repmgr/repmgr.conf cluster show
4.2 配置从节点
4.2.1 编辑repmgr配置文件
根据主节点的配置文件调整
#两个从节点执行,以下只贴出需要修改的部分
vim /data/repmgr/repmgr.conf
####### cluster #######
node_id=2
node_name='node-02'
conninfo='host=10.0.0.42 port=5432 user=repmgr dbname=repmgr connect_timeout=2'vim /data/repmgr/repmgr.conf
####### cluster #######
node_id=3
node_name='node-03'
conninfo='host=10.0.0.43 port=5432 user=repmgr dbname=repmgr connect_timeout=2'
4.2.2 从节点克隆主节点数据
#两个从节点执行
[postgres@repmgr02 ~]$ repmgr -h 10.0.0.41 -U repmgr -d repmgr -f /data/repmgr/repmgr.conf standby clone[postgres@repmgr03 ~]$ repmgr -h 10.0.0.41 -U repmgr -d repmgr -f /data/repmgr/repmgr.conf standby clone
4.2.3 启动从节点
[postgres@repmgr02 ~]$ pg_ctl start -D /data/pgsql/data
[postgres@repmgr03 ~]$ pg_ctl start -D /data/pgsql/data
4.2.4 注册从节点
[postgres@repmgr02 ~]$ repmgr -f /data/repmgr/repmgr.conf standby register
[postgres@repmgr03 ~]$ repmgr -f /data/repmgr/repmgr.conf standby register
4.3 查询集群状态
[postgres@repmgr01 ~]$ repmgr -f /data/repmgr/repmgr.conf cluster show
#主节点执行
select * from pg_stat_replication;
#从节点执行
select * from pg_stat_wal_receiver;
4.4 启动守护进程
#所有节点启动
[postgres@repmgr01 data]$ repmgrd -f /data/repmgr/repmgr.conf --daemonize
[2025-07-21 14:09:21] [NOTICE] redirecting logging output to "/data/repmgr/repmgrd.log"[postgres@repmgr01 data]$ cat /data/repmgr/repmgrd.log
5.测试failover
关闭node-01
[postgres@repmgr01 data]$ pg_ctl stop
waiting for server to shut down.... done
server stopped
查看日志
# node-02节点
[postgres@repmgr02 data]$ tail -f /data/repmgr/repmgrd.log
经过三次重试无法连接node-01
提升node-02作为主节点
node-03作为从节点加入集群
查看集群的最新状态
[postgres@repmgr02 data]$ repmgr -f /data/repmgr/repmgr.conf cluster show
6.故障节点重新加入集群
6.1 断开时间不长时
[postgres@repmgr01 data]$ repmgr node rejoin -f /data/repmgr/repmgr.conf --force-rewind -h 10.0.0.42 -p 5432 -U repmgr -d repmgr
查看集群状态,成功加入加群
[postgres@repmgr02 data]$ repmgr -f /data/repmgr/repmgr.conf cluster show
6.2 断开时间很长时
(1)清空故障节点的数据目录
[postgres@repmgr01 ~]$ cd $PGDATA
[postgres@repmgr01 data]$ rm -rf *(2)从 新的主节点重克隆数据
[postgres@repmgr01 data]$ repmgr -h 10.0.0.42 -U repmgr -d repmgr -f /data/repmgr/repmgr.conf standby clone(3)启动故障节点,并注册
[postgres@repmgr01 data]$ pg_ctl start -D /data/pgsql/data
[postgres@repmgr01 data]$ repmgr -f /data/repmgr/repmgr.conf standby register --force
总结
我们已初步完成 repmgr 的部署,实现了 PostgreSQL 主从自动故障切换(Failover) 和 主从关系重建,但当前方案仍存在应用连接不透明的局限性。
repmgr 仅负责数据库层面的主备切换,不会自动更新应用连接信息,导致业务仍需手动修改数据库 IP 或依赖 DNS 更新,影响高可用性。
完整高可用方案需额外组件:
-
VIP 漂移:通过自定义脚本实现虚拟 IP(VIP)自动漂移,使应用始终连接 VIP,无需修改配置。
-
PgBouncer 动态更新:若使用 PgBouncer 连接池,可在故障切换后自动更新其配置,指向新主库。可参考我的另一篇文章 repmgr+pgbouncer实现对业务透明的高可用切换