【一文搞懂PGSQL】7. PostgreSQL + repmgr + witness 高可用架构

7. PostgreSQL + repmgr + witness 高可用架构

简介

repmgr是一套开源的PostgreSQL集群管理工具,具有非常轻量级的使用特性。具体表现有以下特点:

  • 配置操作简单,可一键式完成相关部署操作;
  • 支持Auto Failover和Manual Switchover;
  • 分布式管理集群节点,易扩展,可在线增删集群节点。
  • witness节点是处理集群主库和备库之间可能存在网络拥塞、延迟、路由等问题影响,导致主库还在正常工作,而备库无法联系主库的场景。
  • 通过设置witness节点可以针对主库与备库之间切换的检查完整性,即辅助备节点监控程序实施主节点网络可见性检查,避免因网络问题导致的脑裂现象。

环境准备

节点角色软件
10.10.8.176primarypg+repmgr
10.10.8.106standbypg+repmgr
10.10.8.177standbypg+repmgr
10.10.8.180standbypg+repmgr

安装postgresql

安装详见标题 2 源码安装配置

https://repmgr.org

免密登录

rm -rf ~/.ssh
ssh-keygen  #一路回车

cd ~/.ssh
mv id_rsa.pub authorized_keys
scp  -r  ~/.ssh  10.10.8.176:/home/postgres/
scp  -r  ~/.ssh  10.10.8.106:/home/postgres/
scp  -r  ~/.ssh  10.10.8.177:/home/postgres/
scp  -r  ~/.ssh  10.10.8.180:/home/postgres/

ssh postgres@10.10.8.176 date
ssh postgres@10.10.8.106 date 
ssh postgres@10.10.8.177 date 
ssh postgres@10.10.8.180 date 

postgresql 重点参数配置 //主库操作

cat  >/pgdata/12/data/postgresql.conf<<'EOF'
# 监听地址
listen_addresses = '0.0.0.0'
# 最大连接数
max_connections = 1000
# 缓冲区大小
shared_buffers = 2GB
# 动态共享内存类型
dynamic_shared_memory_type = posix
# 日志详细程度
wal_level = replica
# 检查点之后第一次页面更改(即使是对提示位进行非关键性的修改)写 FPI 到 WAL 中
wal_log_hints = on
# 重做日志最大物理大小
max_wal_size = 1GB
# 重做日志最小物理大小
min_wal_size = 80MB
# 开启归档
archive_mode = on
# 检查归档
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'
# 最大从库数 多设置点没事
max_wal_senders = 30
# 重做日志保存数量
wal_keep_segments = 128
# 流复制主机发送数据的超时时间
wal_sender_timeout = 60s
# 开启说明如果作为从库可以读
hot_standby = on
# 流复制的最大延迟时间
max_standby_streaming_delay = 30s
# 复制槽的最大数量(复制槽是自动检查行冲突的)
max_replication_slots = 128
# 向主库报告从库当前状态的最大时间
wal_receiver_status_interval = 10s
# 如果有错误的数据复制,是否向主库反馈
hot_standby_feedback = on
# 日志时区(prc  中华人民共和国)
log_timezone = 'PRC'
# 时间格式
datestyle = 'iso, mdy'
# 数据库时区
timezone = 'PRC'
# 系统错误消息的区域设置
lc_messages = 'C'
# 货币格式的区域设置
lc_monetary = 'C'
# 数字格式设置的区域设置
lc_numeric = 'C'
# 时间格式的区域设置
lc_time = 'C'
# 默认文本搜索配置
default_text_search_config = 'pg_catalog.english'
# 日志输出
log_destination = 'stderr'
# 开启日志采集
logging_collector = on 
# 日志路径
log_directory = '/pgdata/12/log'
# 日志格式
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
# 日志权限
log_file_mode = 0600
EOF

# 添加防火墙规则
cat  >>/pgdata/12/data/pg_hba.conf<<'EOF'
host    all             all             0.0.0.0/0               trust
host    replication     repmgr          0.0.0.0/0               trust
EOF

安装repmgr

/ 所有节点安装repmgr

# 下载包
wget  https://repmgr.org/download/repmgr-5.2.0.tar.gz

# 解压
tar xf repmgr-5.2.0.tar.gz

# 进入目录
cd repmgr-5.2.0

# 配置
./configure

# 编译
make

# 安装
make install

# 创建配置文件目录
mkdir -p  /pgdata/repmgr

# 报错 cannot create regular file ‘/usr/local/pg12/lib/postgresql/repmgr.so’: Permission denied
su - root 
chown -R postgres:postgres /usr/local/pg12

配置repmgr

配置用户 // 主库

# 创建用户
createuser -s repmgr
# 创建库
createdb repmgr -O repmgr
# 修改密码
PGPASSWORD=dyh666 psql  -c "alter user repmgr with password 'dyh666';"
# 修改查找目录
PGPASSWORD=dyh666 psql  -c "alter user repmgr set search_path to repmgr ,\"\$user\",public;"

添加配置文件 // 所有节点执行

cat  >/pgdata/repmgr/repmgr.conf<<'EOF'
# 节点ID,高可用集群各节点标识 // 每个节点不同
node_id=1
# 节点名称,高可用集群各节点名称 // 每个节点不同
node_name='pg01-182'
# 本节点数据库连接信息  // 填写本机的IP地址即可
conninfo='host=10.10.8.182  user=repmgr   dbname=repmgr connect_timeout=2'
# pg数据目录
data_directory='/pgdata/12/data'
# 流复制数据库用户,默认使用repmgr
#replication_user='replica'
# repmgr软件目录
repmgr_bindir='/usr/local/pg12/bin/'
# pg软件目录
pg_bindir='/usr/local/pg12/bin'
# 停机超时时间
#shutdown_check_timeout=10
# 日志输出
log_level=INFO
log_file='/pgdata/repmgr/repmgrd.log'
log_status_interval=10
EOF

配置数据库免密 // 所有机器配置

# 配置主备库的密码文件 .pgpass 互相通信使用 
cat >~/.pgpass<<'EOF'
10.10.8.176:5432:repmgr:repmgr:dyh666
10.10.8.106:5432:repmgr:repmgr:dyh666
10.10.8.177:5432:repmgr:repmgr:dyh666
10.10.8.180:5432:repmgr:repmgr:dyh666
EOF

# 授权 // 所以机器配置
chmod 0600 ~/.pgpass

注册完成后可以使用repmgr用户登录数据库repmgr默认库下查看生成的表来确定集群的状态

或者通过repmgr的命令查看相关的状态信息

主库加入集群

# 主库注册到集群
repmgr primary register -f /pgdata/repmgr/repmgr.conf 

# 查看集群状态
repmgr -f /pgdata/repmgr/repmgr.conf cluster show

克隆到其他节点

# 测试克隆  // 非必要操作如果你想使用现有主从做repmgr 则可以忽略
repmgr  standby clone  -h 10.10.8.183 -Urepmgr -d repmgr -f /pgdata/repmgr/repmgr.conf  --dry-run

# 正式执行   // 这里如果提示你输入密码说明你的配置有问题
repmgr  standby clone  -h 10.10.8.182 -Urepmgr -d repmgr -f /pgdata/repmgr/repmgr.conf 

# 启动pgsql
pg_ctl -D /pgdata/12/data -l logfile  start

从库加入集群

# 将 standby 节点注册到集群  --upstream-node-id=1 //指定primary 节点的ID号  
repmgr  standby register -f /pgdata/repmgr/repmgr.conf --upstream-node-id=1

# 查看集群状态
repmgr -f /pgdata/repmgr/repmgr.conf cluster show

配置 witness 节点

以上操作虽然实现了PostgreSQL的切换功能,但是需要手动去执行才能进行切换,witness 节点是监控节点,他可以监控集群的状态,当主库访问不可达或宕机时,可以通过指定的命令自动切换主库,并在代码中实现了防止脑裂的功能。

如果备节点网络上只是和witness或主节点中的一个节点不通,,则很可能存在网络中断,它不应该切换为主节点。如果备节点和witness节点相通,但和主节点不通,这证明不是网络中断,而是主节点本身不可用,因此它可以切换为主节点。

⚠️: witness节点不能在集群内,必须是独立的节点,必须为独立主库!!!

witness节点上初始化一个实例

# 清理旧实例
pg_ctl stop
rm -rf /pgdata/12/data/*
rm -rf /archive/*


# 生产初始化
initdb -A md5 -D $PGDATA -E utf8 --locale=C -W # 配置管理员密码

配置实例

cat  >/pgdata/12/data/postgresql.conf<<'EOF'
# 监听地址
listen_addresses = '0.0.0.0'
# 最大连接数
max_connections = 1000
# 缓冲区大小
shared_buffers = 2GB
# 动态共享内存类型
dynamic_shared_memory_type = posix
# 日志详细程度
wal_level = replica
# 检查点之后第一次页面更改(即使是对提示位进行非关键性的修改)写 FPI 到 WAL 中
wal_log_hints = on
# 重做日志最大物理大小
max_wal_size = 1GB
# 重做日志最小物理大小
min_wal_size = 80MB
# 开启归档
archive_mode = on
# 检查归档
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'
# 最大从库数 多设置点没事
max_wal_senders = 30
# 重做日志保存数量
wal_keep_segments = 128
# 流复制主机发送数据的超时时间
wal_sender_timeout = 60s
# 开启说明如果作为从库可以读
hot_standby = on
# 流复制的最大延迟时间
max_standby_streaming_delay = 30s
# 复制槽的最大数量(复制槽是自动检查行冲突的)
max_replication_slots = 128
# 向主库报告从库当前状态的最大时间
wal_receiver_status_interval = 10s
# 如果有错误的数据复制,是否向主库反馈
hot_standby_feedback = on
# 日志时区(prc  中华人民共和国)
log_timezone = 'PRC'
# 时间格式
datestyle = 'iso, mdy'
# 数据库时区
timezone = 'PRC'
# 系统错误消息的区域设置
lc_messages = 'C'
# 货币格式的区域设置
lc_monetary = 'C'
# 数字格式设置的区域设置
lc_numeric = 'C'
# 时间格式的区域设置
lc_time = 'C'
# 默认文本搜索配置
default_text_search_config = 'pg_catalog.english'
# 日志输出
log_destination = 'stderr'
# 开启日志采集
logging_collector = on 
# 日志路径
log_directory = '/pgdata/12/log'
# 日志格式
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
# 日志权限
log_file_mode = 0600
# 自动切换
shared_preload_libraries ='repmgr'
EOF

# 添加防火墙规则
cat  >>/pgdata/12/data/pg_hba.conf<<'EOF'
host    all             all             0.0.0.0/0               trust
host    replication     repmgr          0.0.0.0/0               trust
EOF

# 启动
 pg_ctl -D /pgdata/12/data -l logfile start

创建用户

# 创建用户
createuser -s repmgr
# 创建库
createdb repmgr -O repmgr
# 修改密码
PGPASSWORD=dyh666 psql  -c "alter user repmgr with password 'dyh666';"
# 修改查找目录
PGPASSWORD=dyh666 psql  -c "alter user repmgr set search_path to repmgr ,\"\$user\",public;"

添加 repmgr 配置

cat  >/pgdata/repmgr/repmgr.conf<<'EOF'
# 节点ID,高可用集群各节点标识 // 每个节点不同
node_id=4
# 节点名称,高可用集群各节点名称 // 每个节点不同
node_name='pg04-180'
# 本节点数据库连接信息  // 填写本机的IP地址即可
conninfo='host=10.10.8.180  user=repmgr   dbname=repmgr connect_timeout=2'
# pg数据目录
data_directory='/pgdata/12/data'
# 流复制数据库用户,默认使用repmgr
#replication_user='replica'
# repmgr软件目录
repmgr_bindir='/usr/local/pg12/bin/'
# pg软件目录
pg_bindir='/usr/local/pg12/bin'
# 停机超时时间
#shutdown_check_timeout=10
# 日志输出
log_level=INFO
log_file='/pgdata/repmgr/repmgrd.log'
log_status_interval=10
EOF

注册witness 节点到集群

# 将 witness 节点注册到集群
repmgr  witness register  -f /pgdata/repmgr/repmgr.conf  -h 10.10.8.183  --upstream-node-id=2 -Urepmgr -d repmgr 

集群检查

# 集群状态拓扑
repmgr -f /pgdata/repmgr/repmgr.conf cluster show

# ssh 连接检查
repmgr -f /pgdata/repmgr/repmgr.conf cluster matrix

# repmgr连接检查
repmgr -f /pgdata/repmgr/repmgr.conf cluster crosscheck

# 显示节点基本信息和复制状态
repmgr -f /pgdata/repmgr/repmgr.conf node status

# 复制状况检查
repmgr -f /pgdata/repmgr/repmgr.conf node check

故障手动切换

主从切换的效果是将执行的命令的从库提升为主库,其他从库指向新主库,旧主库也指向新主库。

# 切换测试
repmgr -f /pgdata/repmgr/repmgr.conf standby switchover --siblings-follow  --force-rewind --dry-run

# 正式切换
repmgr -f /pgdata/repmgr/repmgr.conf standby switchover --siblings-follow  --force-rewind 

# # 集群状态拓扑
repmgr -f   /pgdata/repmgr/repmgr.conf  cluster show

可能遇见的问题:

fe_sendauth: no password supplied

一般是 pg_hba.conf 文件的防火墙权限配置的有问题

故障自动切换

pgsql 添加配置 // 所有节点

# 添加如下配置
cat >>/pgdata/12/data/postgresql.conf<<'EOF'
# 加载repmgr 
shared_preload_libraries = 'repmgr'
EOF

# 重启pg
pg_ctl  restart 

repmgr配置 // 所有节点

# 配置repmgr 配置文件
vim /pgdata/repmgr/repmgr.conf
# 节点ID 唯一的
node_id=4
# 节点名 唯一的
node_name='pg-04-180'
# 本地连接信息
conninfo='host=10.10.8.180 port=5432  user=repmgr dbname=repmgr connect_timeout=2'
# pg数据目录路径
data_directory='/pgdata/12/data/'
# repmgr软件目录
repmgr_bindir='/usr/local/pg12/bin/'
# pg软件目录
pg_bindir='/usr/local/pg12/bin'
# 故障转移方法 自动
failover=automatic
# 等待提升配置
promote_command='/usr/local/pg12/bin/repmgr standby promote -f /pgdata/repmgr/repmgr.conf --log-to-file'
# 故障转移配置
follow_command='/usr/local/pg12/bin/repmgr  standby follow -f /pgdata/repmgr/repmgr.conf --log-to-file --upstream-node-id=%n'
# pg启动命令
service_start_command='pg_ctl -D /pgdata/12/data -l logfile start'
# pg关闭命令
service_stop_command='pg_ctl -D /pgdata/12/data -l logfile stop'
# pg重启命令
service_restart_command='pg_ctl -D /pgdata/12/data -l logfile restart'
# pg重载命令
service_reload_command='pg_ctl -D /pgdata/12/data -l logfile reload'
# pid文件位置
repmgrd_pid_file='/pgdata/repmgr/repmgrd.pid'
# 优先级权重
priority=100
# 日志输出
log_level=ERROR
log_file='/pgdata/repmgr/repmgrd.log'
log_status_interval=10
# 检查主库状态间隔时间
monitor_interval_secs=2
# 探测主库是否可用
connection_check_type='query'
# 尝试连接主库次数
reconnect_attempts=6
# 连接主库失败后再次连接的间隔时间
reconnect_interval=2
# repmgr 启动命令
repmgrd_service_start_command='repmgrd -f /pgdata/repmgr/repmgr.conf'
# repmgr 关闭命令
repmgrd_service_stop_command='kill -9 $(cat /pgdata/repmgr/repmgrd.pid)'

# 启动
repmgrd -f /pgdata/repmgr/repmgr.conf
 
# 关闭
kill -9 `cat /pgdata/repmgr/repmgrd.pid`

集群检查

# 集群状态拓扑
repmgr -f /pgdata/repmgr/repmgr.conf cluster show

# ssh 连接检查
repmgr -f /pgdata/repmgr/repmgr.conf cluster matrix

# repmgr连接检查
repmgr -f /pgdata/repmgr/repmgr.conf cluster crosscheck

# 显示节点基本信息和复制状态
repmgr -f /pgdata/repmgr/repmgr.conf node status

# 复制状况检查
repmgr -f /pgdata/repmgr/repmgr.conf node check

自动切换

# 主库执行
pg_ctl stop

# 查看集群状态
repmgr -f /pgdata/repmgr/repmgr.conf cluster show

恢复的时候执行不了的直接强制执行

但是一定要注意是什么问题,主从同步的问题就不能强制执行,执行了也报错

repmgr 常用命令

# 查看集群状态
repmgr -f /pgdata/repmgr/repmgr.conf cluster show

# primary 节点注册到集群 //主库
repmgr -f /pgdata/repmgr/repmgr.conf  primary register

# 将 standby 节点注册到集群  --upstream-node-id=1 //指定primary 节点的ID号  
repmgr standby register -f /pgdata/repmgr/repmgr.conf --upstream-node-id=1

# 强制注册一个standby 节点
repmgr  standby register    --force  -d 'host=10.10.8.176 port=5432 user=repmgr password=dyh666'


# 将 witness 节点注册到集群
repmgr -f /pgdata/repmgr/repmgr.conf  -h 10.10.8.176  --upstream-node-id=1 -Urepmgr -d repmgr witness register

# 集群删除一个standby节点
repmgr standby unregister -f /pgdata/repmgr/repmgr.conf --node-id=1

# 集群删除一个primary节点
repmgr primary unregister -f /pgdata/repmgr/repmgr.conf --node-id=1

# 集群删除 witness节点
repmgr witness  unregister -f /pgdata/repmgr/repmgr.conf   --node-id=4

# 检查切换  // 从节点执行
repmgr -f /pgdata/repmgr/repmgr.conf  standby switchover --siblings-follow --force-rewind --dry-run

# 手动切换切换  // 从节点执行
repmgr -f /pgdata/repmgr/repmgr.conf  standby switchover --siblings-follow --force-rewind

# 清理监控数据
repmgr cluster cleanup -f /pgdata/repmgr/repmgr.conf --node-id=4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值