当前位置: 首页 > news >正文

Postgresql14+Repmgr部署

                      PostgreSQL 主库(Primary)

                                  ↑      ↑

                                   |      |

Standby 节点 ←→ Standby 节点(全为 Streaming Replication)

+ 每个节点都运行 repmgr(管理工具)和可选 repmgrd(守护进程)

+ 一个共享的 repmgr 管理数据库用于记录集群拓扑和状态

PostgreSQL 原生支持流复制,但不内建高可用管理机制。repmgr 构建在 PostgreSQL 基础上,负责主从拓扑管理、复制配置、故障转移(failover)、主备切换(switchover)等功能。

工作机制核心组成

🔹 1. 数据库复制机制(Streaming Replication)

  • PostgreSQL 提供主库 WAL 日志流式复制给 standby 节点。
  • repmgr 通过 standby clone 自动搭建好复制关系。

🔹 2. 集群信息存储在 repmgr 数据库表中

  • 所有节点都注册到一个共用的 PostgreSQL 数据库(一般为主库):
    • 表包括 repl_nodes、repl_events 等
  • 每个节点使用自己的 repmgr.conf 定义身份、连接信息、优先级等

🔹 3. 故障检测与自动切换(repmgrd 守护进程)

  • 每个节点运行 repmgrd:
    • 轮询主库健康状态(连接、ping、同步延迟)
    • 若发现主库故障,优先级最高、距离最近的 standby 发起 promote
    • 其他 standby 节点随后自动执行 follow_command 连接新的主库

⚠️ 要实现自动 failover,必须启用 repmgrd,并配置好 promote_command 与 follow_command。

🔹 4. 集群维护工具

  • repmgr cluster show:查看拓扑和状态
  • repmgr standby clone:克隆主库数据到 standby
  • repmgr standby register:注册节点信息
  • repmgr standby follow:变更 standby 的上游
  • repmgr standby promote:提升为主库
  • repmgr cluster switchover:有序主备切换

🔹 5. 无共享存储、无仲裁机制

  • repmgr不提供仲裁(quorum),也不提供 VIP 自动漂移
  • 所以通常结合 keepalived、Pacemaker、HAProxy 等组件用于漂移或路由

一、环境准备

1.1 软件版本:

postgresql 14.6

repmgr 5.3.3    下载地址:https://github.com/EnterpriseDB/repmgr/releases

centos7.9

序号

主机

IP地址

端口

备注

1

pgtest1

192.168.24.11

5432

2

pgtest2

192.168.24.12

5432

3

Pgtest3

192.168.24.13

5432

1.2 配置hosts文件

cat >>/etc/hosts<<EOF

192.168.24.11 pgtest1

192.168.24.12 pgtest2

192.168.24.13 pgtest3

EOF

1.3 同步时间

所有服务器的时区及时间需要保持同步 

 timedatectl set-timezone Asia/Shanghai

1.4 关闭防火墙和 selinux

systemctl stop firewalld 
systemctl disable firewalld 
vi /etc/selinux/config 
SELINUX=disabled

二、pg数据库安装

--所有节点执行相同操作

2.1 安装依赖包

yum install -y perl-ExtUtils-Embed readline zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel python-devel gcc-c++ openssl-devel cmake gcc* readline-devel zlib bison flex bison-devel flex-devel openssl openssl-devel

2.2 创建用户和目录

  • 创建用户、组

groupadd  postgres

echo "postgres" | passwd --stdin postgres

  • 创建目录

mkdir -p /postgresql/{pgdata,archive,pg14,soft}

chown -R postgres. /postgresql

chmod -R 700 /postgresql

2.3 配置postgres用户环境变量

su - postgres

cat >>~/.bash_profile<<EOF

export PGHOME=/postgresql/pg14

export PGDATA=/postgresql/pgdata

export PATH=$PGHOME/bin:$PATH

export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH

EOF

--立即生效

source ~/.bash_profile

2.4 上传安装介质并解压

tar zxvf postgresql-14.6.tar.gz

2.5 编译安装postgresql

./configure --prefix=/postgresql/pg14 --with-pgport=5432

make world &&make install-world

2.6 配置数据库(主库)

--初始化数据库

[postgres@pgtest1 ~]$ initdb -D $PGDATA

---修改参数

  • 检查并修改postgresql.conf以下参数

listen_addresses = '*' 

archive_mode = on 

archive_command = 'cp %p /postgresql/arch/%f' 

wal_level = replica    

log_destination = 'csvlog'

logging_collector = on

hot_standby = on

wal_log_hints = on

  • 修改pg_hba.conf文件,添加以下参数

host    all    all     0.0.0.0/0      trust

host    all    all         0.0.0.0/0       scram-sha-256

host   replication     all     0.0.0.0/0    trust

host   replication     all     0.0.0.0/0       scram-sha-256

本实验流复制用户使用postgres超级用户。

--启动主库。

[postgres@pgtest1 ~]$ pg_ctl -D /postgresql/pgdata -l logfile start

--设置postgres密码

[postgres@pgtest1 ~]$ psql

psql (14.6)

Type "help" for help.

postgres=# alter user postgres password 'postgres';

2.7 创建备库

--复制备库1

[postgres@pgtest2 ~]$ pg_basebackup -Fp -Pv -Xs -R -h 192.168.24.11 -p 5432 -Upostgres -D /postgresql/pgdata

--启动备库

[postgres@pgtest2 ~]$ pg_ctl start

--复制备库2

[postgres@pgtest3 ~]$ pg_basebackup -Fp -Pv -Xs -R -h 192.168.24.11 -p 5432 -Upostgres -D /postgresql/pgdata

--启动备库

[postgres@pgtest3 ~]$ pg_ctl start

2.8 查看数据库状态

--主库查看

postgres=# select * from pg_stat_replication;

[postgres@pgtest1 ~]$ ps -ajxf|grep postgres

三、3节点配置ssh互信

–-配置集群内postgres用户之间互信

---每个节点执行脚本setup_ssh_trust.ssh

#!/bin/bash
 
# SSH 互信目标主机名
NODES=("pgtest1" "pgtest2" "pgtest3")
 
# 当前主机名
HOSTNAME=$(hostname)
 
# 切换到 postgres 用户执行(若当前非 postgres 用户)
if [ "$(whoami)" != "postgres" ]; then
  echo "请使用 postgres 用户执行此脚本。"
  exit 1
fi
 
# 创建 .ssh 目录和 SSH 密钥(如果不存在)
SSH_DIR="$HOME/.ssh"
KEY_FILE="$SSH_DIR/id_rsa"
 
mkdir -p "$SSH_DIR"
chmod 700 "$SSH_DIR"
 
if [ ! -f "$KEY_FILE" ]; then
  echo "生成 SSH 密钥对..."
  ssh-keygen -t rsa -b 4096 -N "" -f "$KEY_FILE"
else
  echo "SSH 密钥已存在,跳过生成。"
fi
 
# 遍历节点,配置 SSH 信任
for NODE in "${NODES[@]}"; do
  if [ "$NODE" == "$HOSTNAME" ]; then
    continue
  fi
 
  echo "将公钥复制到 $NODE..."
  ssh-copy-id -i "$KEY_FILE.pub" "postgres@$NODE"
done
 
echo "SSH 互信配置完成!建议测试:"
for NODE in "${NODES[@]}"; do
  if [ "$NODE" != "$HOSTNAME" ]; then
    echo "  ssh $NODE"
  fi
done

chmod +x  setup_ssh_trust.ssh

上述过程为配置3节点间的postgres的用户的互信。用date 检验,确保集群内节点能通过postgres用户互相访问。

ssh pgtest1 date
ssh pgtest2 date
ssh pgtest3 date

四、安装repmgr(源码安装)

--所有节点执行相同操作

4.1 上传介质并解压

repmgr-5.3.3.tar.gz

tar zxvf repmgr-5.3.3.tar.gz

4.2  编译安装

[postgres@pgtest1 soft]$ cd repmgr-5.3.3/

[postgres@pgtest1 repmgr-5.3.3]$

./configure PG_CONFIG=/postgresql/pg14/bin/pg_config

[postgres@pgtest1 repmgr-5.3.3]$ make &&make install

--查看已安装版本

[postgres@pgtest1 postgresql-14.6]$ repmgr --version

repmgr 5.3.3

4.3 主库创建repmgr数据库存储元数据

create database repmgr;

4.4 配置pg_hba(所有节点)

host    all    postgres     192.168.24.0/24      trust

host    all    all         0.0.0.0/0       scram-sha-256

host   replication     postgres     192.168.24.0/24    trust

host   replication     all     0.0.0.0/0       scram-sha-256

如上,增加红色条目。

本实验采用默认超级用户postgres,并设置trust使postgres用户可以免密访问集群节点间的数据库。

或者

如果想让postgres在此处也为密码校验,则需要将trust改为md5或者scram-sha-256并在本地创建.pgpass文件,操作如下

su - postgres
touch ~/.pgpass  
chmod 0600 ~/.pgpass 
echo "192.168.24.11:5432:repmgr:psotgres:postgres 
192.168.24.12:5432:repmgr:psotgres:postgres
 ">> ~/.pgpass

使用密码校验需要注意密码的加密格式,留意pg_authid系统表和password_encryption参数。

--节点间测试是否可以免密访问数据库

[postgres@pgtest2 ~]$ psql -h 192.168.24.11 -p 5432 -Upostgres
psql (14.6)
Type "help" for help.
postgres=#

4.5 配置postgresql.conf(所有节点)

 PostgreSQL 配置文件中启用 repmgr 扩展模块(作为 shared library 加载),此操作是启动repmgr守护进行的前提。
shared_preload_libraries = 'repmgr'
 
重启生效
pg_ctl restart

4.5 停库并删除数据文件(备库)

因为备库要通过repmgr同步来自主库的数据,所以要事先删除备库数据。

--停库
[postgres@pgtest2 pgdata]$ pg_ctl stop
[postgres@pgtest3 pgdata]$ pg_ctl stop
 
--删除数据
[postgres@pgtest2 pgdata]$ rm -rf ./*
[postgres@pgtest3 pgdata]$ rm -rf ./*

五、repmgr注册及配置

5.1 配置repmgr.conf文件

--主库配置repmgr.conf文件
[postgres@pgtest1 postgresql-14.6]$ vi /postgresql/repmgr.conf
node_id=1
node_name='pgtest1'
conninfo='host=192.168.24.11 port=5432 user=postgres dbname=repmgr'
data_directory='/postgresql/pgdata'
replication_user='postgres'
replication_type='physical'
pg_bindir='/postgresql/pg14/bin'
monitoring_history=yes
monitor_interval_secs=5
log_level='debug'
log_file='/postgresql/repmgr.log'
failover='automatic'
promote_command='repmgr standby promote'
follow_command='repmgr standby follow  -W -f /postgresql/repmgr.conf'
connection_check_type=ping
reconnect_attempts=3
reconnect_interval=10
 
--从库1配置repmgr.conf文件
[postgres@pgtest2 ~]$ vi /postgresql/repmgr.conf
node_id=2
node_name='pgtest2'
conninfo='host=192.168.24.12 port=5432 user=postgres dbname=repmgr'
data_directory='/postgresql/pgdata'
replication_user='postgres'
replication_type='physical'
pg_bindir='/postgresql/pg14/bin'
monitoring_history=yes
monitor_interval_secs=5
log_level='debug'
log_file='/postgresql/repmgr.log'
failover='automatic'
promote_command='repmgr standby promote -f /postgresql/repmgr.conf'
follow_command='repmgr standby follow -f /postgresql/repmgr.conf -W'
connection_check_type=ping
reconnect_attempts=3
reconnect_interval=10
 
--从库2配置repmgr.conf文件
[postgres@pgtest3 ~]$ vi /postgresql/repmgr.conf
node_id=3
node_name='pgtest3'
conninfo='host=192.168.24.13 port=5432 user=postgres dbname=repmgr'
data_directory='/postgresql/pgdata'
replication_user='postgres'
replication_type='physical'
pg_bindir='/postgresql/pg14/bin'
monitoring_history=yes
monitor_interval_secs=5
log_level='debug'
log_file='/postgresql/repmgr.log'
failover='automatic'
promote_command='repmgr standby promote -f /postgresql/repmgr.conf'
follow_command='repmgr standby follow -f /postgresql/repmgr.conf -W'
connection_check_type=ping
reconnect_attempts=3
reconnect_interval=10

5.2 使用repmgr命令注册主库

[postgres@pgtest1 ~]$ repmgr -f /postgresql/repmgr.conf primary register --force
INFO: connecting to primary database...
DEBUG: connecting to: "user=postgres dbname=repmgr host=192.168.24.11 port=5432 connect_timeout=2 fallback_application_name=repmgr options=-csearch_path="
NOTICE: attempting to install extension "repmgr"
NOTICE: "repmgr" extension successfully installed
NOTICE: primary node record (ID: 1) registered

5.3 使用repmgr命令克隆备库(备库执行)

--备库1
--check
[postgres@pgtest2 postgresql]$ repmgr -h 192.168.24.11 -p5432 -Upostgres -drepmgr -f /postgresql/repmgr.conf standby clone --dry-run
--clone
[postgres@pgtest2 pgdata]$ repmgr -h 192.168.24.11 -p5432 -Upostgres -drepmgr -f /postgresql/repmgr.conf standby clone
--启动备库
[postgres@pgtest2 pgdata]$ pg_ctl start
 
--备库2
--check
[postgres@pgtest3 postgresql]$ repmgr -h 192.168.24.11 -p5432 -Upostgres -drepmgr -f /postgresql/repmgr.conf standby clone --dry-run
--clone
[postgres@pgtest3 pgdata]$ repmgr -h 192.168.24.11 -p5432 -Upostgres -drepmgr -f /postgresql/repmgr.conf standby clone
--启动备库
[postgres@pgtest3 pgdata]$ pg_ctl start

5.4 查看数据库进程

--主库查看postgres进程
select * from pg_stat_replication;
[postgres@pgtest1 postgresql-14.6]$ ps -ajxf|grep postgres

5.5 使用repmgr命令注册备库

--注册备库1
[postgres@pgtest2 pgdata]$ repmgr -f /postgresql/repmgr.conf standby register --force
INFO: connecting to local node "pgtest2" (ID: 2)
DEBUG: connecting to: "user=postgres dbname=repmgr host=192.168.24.12 port=5432 connect_timeout=2 fallback_application_name=repmgr options=-csearch_path="
INFO: connecting to primary database
DEBUG: connecting to: "user=postgres dbname=repmgr host=192.168.24.11 port=5432 connect_timeout=2 fallback_application_name=repmgr options=-csearch_path="
WARNING: --upstream-node-id not supplied, assuming upstream node is primary (node ID: 1)
INFO: standby registration complete
NOTICE: standby node "pgtest2" (ID: 2) successfully registered
--注册备库2
[postgres@pgtest3 pgdata]$ repmgr -f /postgresql/repmgr.conf standby register –force
INFO: connecting to local node "pgtest3" (ID: 3)
DEBUG: connecting to: "user=postgres dbname=repmgr host=192.168.24.13 port=5432 connect_timeout=2 fallback_application_name=repmgr options=-csearch_path="
INFO: connecting to primary database
DEBUG: connecting to: "user=postgres dbname=repmgr host=192.168.24.11 port=5432 connect_timeout=2 fallback_application_name=repmgr options=-csearch_path="
WARNING: --upstream-node-id not supplied, assuming upstream node is primary (node ID: 1)
INFO: standby registration complete
NOTICE: standby node "pgtest3" (ID: 3) successfully registered

5.6 查看集群状态

--任意节点查询
[postgres@pgtest1 postgresql]$ repmgr -f /postgresql/repmgr.conf cluster show

5.7 启动repmgr守护进程

#所有节点执行
[postgres@pgtest1 ~]$ repmgrd -f /postgresql/repmgr.conf -d
[2025-05-08 12:45:21] [NOTICE] redirecting logging output to "/postgresql/repmgr.log"
 
[postgres@pgtest1 ~]$ ps -ef|grep repmgr
postgres  30933  30899  0 12:45 ?        00:00:00 postgres: postgres repmgr 192.168.24.13(58604) idle
postgres  30941  30899  0 12:45 ?        00:00:00 postgres: postgres repmgr 192.168.24.12(46244) idle
postgres  30962  30899  0 12:45 ?        00:00:00 postgres: postgres repmgr 192.168.24.11(40242) idle
postgres  30964      1  0 12:45 ?        00:00:00 repmgrd -f /postgresql/repmgr.conf -d
postgres  30971  22092  0 12:45 pts/1    00:00:00 grep --color=auto repmgr
[postgres@pgtest1 ~]$ vi /postgresql/pgdata/postgresql.conf

六、集群切换

注意:切换前要查看各节点同步状态,保证LSN唯一且相同,否则切换会失败并导致主库宕机。

select * from pg_stat_replication;

6.1 停用repmgrd、手动switchover(3次)

6.1.1 pgtest2节点手动切换

[postgres@pgtest2 log]$ repmgr -f /postgresql/repmgr.conf standby switchover --siblings-follow

参数说明

  • -f: 指定配置文件路径(必须)
  • switchover: 平滑切换命令
  • --siblings-follow: 让所有其他备库自动跟随新的主节点(非常推荐)

---查看集群状态

[postgres@pgtest2 pgdata]$ repmgr -f /postgresql/repmgr.conf cluster show

6.2 pgtest3节点手动切换

[postgres@pgtest3 ~]$ repmgr -f /postgresql/repmgr.conf standby switchover --siblings-follow

---查看集群状态

[postgres@pgtest3 ~]$ repmgr -f /postgresql/repmgr.conf cluster show

6.3 pgtest1节点手动切换

[postgres@pgtest1 ~]$ repmgr -f /postgresql/repmgr.conf standby switchover --siblings-follow

---查看集群状态

[postgres@pgtest1 ~]$ repmgr -f /postgresql/repmgr.conf cluster show

6.2 停止主库服务(最常用)

#实现自动failover,必须启用 repmgrd守护进程

关闭前集群状态

--主库关闭

[postgres@pgtest1 ~]$ pg_ctl stop

waiting for server to shut down.... done

server stopped

--任意节点查看集群状态

[postgres@pgtest2 log]$  repmgr -f /postgresql/repmgr.conf cluster show

等待数秒后,发现pgtest2 standby节点自动升主。

当停止主库服务后,repmgr 成功在某个 standby 节点执行了自动 promote 升主。此时,原主库重启后仍处于“孤立”状态,不会自动加入集群,也不能直接变回 standby。要恢复集群正常状态,需要手动进行“rejoin”(重新加入集群)操作。

--重新将原主库加入集群

#关闭原主库

pg_ctl stop

#清空原主库数据目录

[postgres@pgtest1 pgdata]$ rm -rf ./*

#使用新主库克隆数据

[postgres@pgtest1 pgdata]$ repmgr -h 192.168.24.12 -p5432 -Upostgres -drepmgr -f /postgresql/repmgr.conf standby clone

#启动原主库

pg_ctl start

#注册该节点为standby节点

[postgres@pgtest1 pgdata]$ repmgr -f /postgresql/repmgr.conf standby register

#明确跟随当前主库,否则其upstream为空

[postgres@pgtest1 pgdata]$ repmgr -f /postgresql/repmgr.conf standby follow

#任意节点查看集群状态

[postgres@pgtest1 pgdata]$  repmgr -f /postgresql/repmgr.conf cluster show

相关文章:

  • sentinel滑动时间窗口算法详解
  • 性能测试场景题
  • leetcode hot100刷题日记——10.螺旋矩阵
  • Day 0015:Metasploit 基础解析
  • ollama接口配合chrome插件实现商品标题和描述生成
  • 手写简单的tomcat
  • 硅基计划2.0 学习总结 叁
  • fscan教程1-存活主机探测与端口扫描
  • nginx动态控制前端版本
  • mysql安全管理
  • LeetCode 1340. 跳跃游戏 V(困难)
  • SpringCloud(三)
  • window 显示驱动开发-视频内存供应和回收(一)
  • Qt状态机QStateMachine
  • 插值算法 - 图像缩放插值QT
  • 简说Qt信号和槽
  • Flink中Kafka连接器的基本应用
  • Qt5、C++11 获取wifi列表与wifi连接
  • 论文流程图mermaid解决方案
  • Java集合框架深度剖析:结构、并发与设计模式全解析
  • wordpress制作关于页面/长沙seo关键词
  • 建网站做站在/常用的seo工具
  • 二维码活码生成器在线制作/华为seo诊断及优化分析
  • 哪些网站做任务可以赚钱的/市场营销在线课程
  • 网站配色的方案/百度投诉电话24小时
  • 一个人做运营网站/全达seo