基于 pg_auto_failover的高可用PostgreSQL

news/2025/3/26 5:15:05/文章来源:https://www.cnblogs.com/obitoma/p/18788919

基于 pg_auto_failover

参考:

  • GitHub - hapostgres/pg_auto_fa...
  • Site Unreachable
  • PostgreSQL高可用-pg_auto_failover的简单使用介绍

pg_auto_failover 的需求和能力列表

1. 需求(安装和运行所需条件)

基础要求

条件 详细信息
PostgreSQL 版本 支持 PostgreSQL 13-17
操作系统 Linux(推荐)或 macOS(可测试)
依赖软件 pg_autoctl(pg_auto_failover CLI 工具),PostgreSQL 服务器
存储和网络 主库与备库网络稳定,支持同步或异步复制
监控节点 至少 3 台服务器 才能完全避免脑裂

架构要求

条件 详细信息
最少服务器数量 2 台(但可能会有脑裂风险)
推荐服务器数量 3 台(主库、备库、监控)
数据复制方式 默认异步(提高性能),支持同步(提高一致性)
PostgreSQL 流复制 pg_auto_failover 自动管理

2. 能力(提供的功能)

高可用性(HA)

功能 详细信息
自动主备切换 主节点故障时,自动提升备节点
自动重新加入集群 原主节点恢复后自动降级为备节点
数据复制 默认异步(高性能),支持同步复制(一致性更高)
防止脑裂 需要监控节点2 台服务器时可能有脑裂风险

集群管理

功能 详细信息
自动 PostgreSQL 配置 无需手动配置流复制
集群状态管理 监控节点会管理 主/备/备用节点
拓扑结构 仅支持 主 - 备架构(1 主 1 备)
自动故障检测 检测主库状态,自动触发故障转移

管理与监控

功能 详细信息
管理工具 pg_autoctl CLI 提供简单的命令行管理
集群健康检查 定期检查节点状态
支持日志与指标监控 可与 Prometheus/Grafana 结合

额外特性

功能 详细信息
支持 Load Balancer 允许配置读流量均衡
多数据中心部署 支持跨数据中心 HA(需要额外配置)

3. 适用场景

适用 详细信息
适用于 高可用 PostgreSQL、自动主备切换、低运维成本
不适用于 仅 2 台服务器(可能有脑裂风险),多主架构

4. 典型架构

组件 作用
主库(Primary) 处理所有写请求,并同步数据到备库
备库(Secondary) 复制主库数据,在主库故障时提升为新主库
监控节点(Monitor) 负责监控集群状态,决定故障转移

5. 结论

  • 如果有 3 台服务器(主、备、监控)→ pg_auto_failover 是合适的,自动化程度高,管理简单
  • 如果只有 2 台服务器可能会有脑裂风险,建议改用 Patroni + watchdog

安装部署

定义基本信息

本次安装的环境:

环境
操作系统 Ubuntu 22.04.5 LTS
数据库 PostgreSQL 14.15 (Ubuntu 14.15-0ubuntu0.22.04.1)
pg-auto-failover-cli 1.6.3-1
仲裁机 192.192.192.9
主机 192.192.192.204
备机 192.192.192.205
VIP 192.192.192.260

在每个主机执行:

# 可能需要修改的
monitor_ip="192.192.192.9" # 仲裁
primary_ip="192.192.192.204" # 主
secondary_ip="192.192.192.205" # 备# 几个路径,可以在后边安装好数据库后再确认
pgdata="/var/lib/postgresql/14/main/"
pgbin="/usr/lib/postgresql/14/bin"
pgconfig="/etc/postgresql/14/main/"# 密码含有@则考虑后续命令中手动填充
autoctl_node_pwd="autoctl_ceni_2025"
replication_pwd="replication_ceni_2025"
export autoctl_node_pwd=$autoctl_node_pwd
export replication_pwd=$replication_pwd# 无需修改
cat >> /etc/profile << EOF
export monitor_ip=$monitor_ip
export primary_ip=$primary_ip
export secondary_ip=$secondary_ip
export pgdata=$pgdata
export pgbin=$pgbin
export pgconfig=$pgconfig
export PGDATA=$pgdata
export PGHOME=$pgdata
export PATH=\$PATH:$pgbin
EOFsource /etc/profileecho "$monitor_ip monitor" >> /etc/hosts
echo "$primary_ip primary" >> /etc/hosts
echo "$secondary_ip secondary" >> /etc/hosts

![[Pasted image 20250207132357.png]]

安装数据库

分别在主备和仲裁机上安装:

apt update
apt install -y postgresql-common
# 调整配置文件以阻止初始化cluster
echo 'create_main_cluster = false' | sudo tee -a /etc/postgresql-common/createcluster.confapt install -y --no-install-recommends postgresql-14
apt install -y pg-auto-failover-cli 

执行 pg_autoctl 测试:

![[Pasted image 20250206150642.png]]

仲裁节点 执行

创建监控节点:

hostnamectl set-hostname monitorsu - postgres -c "pg_autoctl create monitor --auth scram-sha-256 \--pgdata $pgdata \--pgport 5432 \--hostname monitor \--ssl-self-signed"

创建服务启动服务 (root 用户):

pg_autoctl -q show systemd --pgdata $pgdata > /usr/lib/systemd/system/pgautofailover.servicesystemctl daemon-reload
systemctl enable pgautofailover.service
systemctl start pgautofailover.service
systemctl status pgautofailover.service

创建密码:

su - postgres -c "psql -d pg_auto_failover -c \"alter user autoctl_node password '$autoctl_node_pwd';\""

主节点 执行

hostnamectl set-hostname primarysu - postgres -c "pg_autoctl create postgres --auth scram-sha-256 \--hostname primary \--ssl-self-signed \--monitor 'postgres://autoctl_node:$autoctl_node_pwd@monitor:5432/pg_auto_failover?sslmode=require'"su - postgres -c "pg_autoctl config set replication.password $replication_pwd"

创建服务 (root 用户):

pg_autoctl -q show systemd --pgdata $pgdata > /usr/lib/systemd/system/pgautofailover.servicesystemctl daemon-reload
systemctl enable pgautofailover.service
systemctl start pgautofailover.service
systemctl status pgautofailover.service

创建流复制用户:

su - postgres -c "psql -d postgres -c \"ALTER USER pgautofailover_replicator PASSWORD '$replication_pwd';\""

备节点 执行

# 备节点要执行
hostnamectl set-hostname secondarysu - postgres -c "export PGPASSWORD=$replication_pwd; export PGSSLMODE=require; pg_autoctl create postgres --auth scram-sha-256 \--hostname secondary \--ssl-self-signed \--monitor 'postgres://autoctl_node:$autoctl_node_pwd@monitor:5432/pg_auto_failover?sslmode=require'"su - postgres -c "pg_autoctl config set replication.password $replication_pwd"

创建服务启动服务 (root 用户):

pg_autoctl -q show systemd --pgdata $pgdata > /usr/lib/systemd/system/pgautofailover.servicesystemctl daemon-reload
systemctl enable pgautofailover.service
systemctl start pgautofailover.service
systemctl status pgautofailover.service

查看状态

su - postgres -c "pg_autoctl show state"

![[Pasted image 20250206180129.png]]

在一主多从情况下手动提升某个从节点为主库(在要提升的从节点 node_2 上执行):

适用场景

  • 你需要强制进行主从切换,比如主节点已经失效,但故障转移没有自动发生。
  • 你希望人为干预集群的主从角色变化。
su - postgres -c "pg_autoctl perform promotion -name node_2"

如果需要手动触发主备切换:

  • 该命令用于 手动触发主备切换(switchover)。
  • 作用是 让当前 primary(主节点)降级为 secondary,同时 让当前最合适的 secondary(备节点)提升为 primary
su - postgres -c "pg_autoctl perform switchover"

![[Pasted image 20250207161040.png]]

如果有异常需要关闭 pg_autoctl :

# 1. 首先停止节点服务
su - postgres -c "pg_autoctl stop"# 2. 删除节点
su - postgres -c "pg_autoctl drop node --pgdata $PGDATA"# 3. 清理数据目录和配置文件
su - postgres -c "rm -rf $PGDATA/* && rm -rf /var/lib/postgresql/.local/pg_autoctl/*"

测试

当前状态 node1 为主,node2 为备

当主机关机,会检测到 timeout

![[Pasted image 20250207155841.png]]

然后备机会变为 read-write 模式

![[Pasted image 20250207155914.png]]

主机重启后,备机 node2 自动升级为 primary,原主机 node1 降级为 secondary.

![[Pasted image 20250207160051.png]]

在当前的主服务器 node2 上创建表:

su - postgres -c "psql -c \"CREATE TABLE test_table (id SERIAL PRIMARY KEY, name TEXT);INSERT INTO test_table (name) VALUES ('test');\""

在备服务器 node1 查看:

su - postgres -c "psql -c \"SELECT * FROM test_table;\""

![[Pasted image 20250207160446.png]]

如果需要在仲裁机上删除某节点:

su - postgres -c "pg_autoctl drop node --pgdata $pgdata --name node_2 --force"

创建用户

su - postgres -c "psql -c \"CREATE USER dbuser WITH PASSWORD 'gg@Ceni@2025#gg';\""# 允许用户远程连接
echo "host    all       dbuser  192.192.192.0/24  md5" >> $pgconfig/pg_hba.conf

查看用户,应该能够在主备机上同步:

su - postgres -c "psql -c '\du'"

删除用户:

su - postgres -c "psql -c 'DROP USER dbuser;'"

注意

状态机 Monitor 挂了对集群使用完全没有影响。但是此时如果集群里面的机器在挂一台,是没有办法自动进行故障转移的,因为我们失去了状态机。

配置 Keepalived

在主机和备机安装 Keepalived

apt install keepalived

主节点配置文件:

cat > /etc/keepalived/keepalived.conf << EOF
global_defs {router_id LVS_DEVEL
}vrrp_script chk_pgdb {script "/etc/keepalived/check.sh"interval 5weight 2
}vrrp_instance VI_1 {state MASTERinterface ens192 # 网卡编号virtual_router_id 99 # 同一集群内keepalived id 应该相同priority 100 # 优先级advert_int 1authentication {auth_type PASSauth_pass ceni@pg@2025}virtual_ipaddress {192.192.192.240}
}
EOF

备节点配置文件:

cat > /etc/keepalived/keepalived.conf << EOF
global_defs {router_id LVS_DEVEL
}vrrp_script chk_pgdb {script "/etc/keepalived/check.sh"interval 5weight 2
}vrrp_instance VI_1 {state BACKUPinterface ens192 # 网卡编号virtual_router_id 99 # 同一集群内keepalived id 应该相同priority 99 # 优先级advert_int 1nopreemtauthentication {auth_type PASSauth_pass ceni@pg@2025}virtual_ipaddress {192.192.192.240}
}
EOF

创建存活检查脚本和通知脚本

cat > /etc/keepalived/check.sh << EOF
#!/bin/sh
# 本脚本用于 Keepalived 检查 PostgreSQL 状态,通过 su - postgres -c "psql -qtAX -c \"select pg_is_in_recovery();\""
# 执行查找 pg_is_in_recovery() 的结果。如果结果为 "f",表示当前节点为主节点;否则为备节点。
#
# 请确保:
# 1. psql 已安装,且当前系统中 postgres 用户正常配置了访问 PostgreSQL 的权限。
# 2. 日志输出使用 logger (可选) 以便调试。# 执行 SQL 查询,获取 pg_is_in_recovery() 返回值
ROLE=$(su - postgres -c "psql -qtAX -c \"select pg_is_in_recovery();\"" 2>/dev/null)# 记录日志
logger "Keepalived check: pg_is_in_recovery() returned '${ROLE}'"# 判断结果,如果返回 f 则为主节点
if [ "$ROLE" = "f" ]; thenexit 0
elseexit 1
fi
EOF
cat > /etc/keepalived/notify.sh << EOF
#!/bin/bash
# notify.shecho $1 $2 is in $3 state > /etc/keepalived/keepalive.$1.$2.state
EOF
cat >  /etc/keepalived/getstate.sh << EOF
#!/bin/bash
# getstate.shcat /etc/keepalived/keepalive.*.*.state
EOF

启动服务

systemctl enable --now keepalived
systemctl status keepalived.service

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904702.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《ESP32-S3使用指南—IDF版 V1.6》第十三章 UART实验

第十三章 UART实验 1)实验平台:正点原子DNESP32S3开发板 2)章节摘自【正点原子】ESP32-S3使用指南—IDF版 V1.6 3)购买链接:https://detail.tmall.com/item.htm?&id=768499342659 4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/esp32/ATK-…

AI与.NET技术实操系列(九):总结篇 ── 探讨.NET 开发 AI 生态:工具、库与未来趋势

1. 引言 本文作为本系列的最后一篇,旨在全面探讨 .NET 生态中与 AI 相关的工具、库、框架和资源,帮助开发者了解如何在 .NET 环境中开发 AI 应用。我们将分析 Microsoft 的 AI 战略、核心工具和库(如 ML.NET、Azure AI SDK 和 Semantic Kernel)、.NET 9 的新特性,以及社区…

windows 查询内存型号

1、通过任务管理器-性能 2、运行-cmd wmic memorychip get Speed,SMBIOSMemoryType根据返回的 SMBIOSMemoryType 值判断:24 表示 DDR3 26 表示 DDR4 34 表示 DDR5。‌2

更换数据库连接池失败

更换数据库连接池失败 将数据库连接池更换为druid,一直无法更换,保持默认的HiKari原因: 配置文件代码错误,在下图中,可以看见一个黄线的警告,这里出现了关键词错误.这个错误是导致出现配置失败的原因. 教训:配置文件的警告需要引起足够的重视.

SANA-Sprint:基于连续时间一致性蒸馏的单步扩散模型,0.1秒即可生成图像

扩散模型已成为现代文本到图像 (T2I) 生成技术的核心,能够生成高质量图像,但其迭代式推理过程导致生成速度缓慢。多数模型通常需要 20–50 个去噪步骤,这严重制约了其在实时应用中的部署。 现有的蒸馏技术旨在加速扩散模型的采样过程,然而,这些方法往往会引入稳定性问题,…

华为无线网络射频调优及WLAN跨VLAN的三层漫游示例

1.业务需求企业用户通过WLAN接入网络,以满足移动办公的最基本需求。 在覆盖区域内移动发生跨VLAN的漫游时,不影响用户的业务使用。2.组网需求AC组网方式:旁挂三层组网。DHCP部署方式:AC作为DHCP服务器为AP分配IP地址。 汇聚交换机SwitchB作为DHCP服务器为STA分配IP地址。业…

大型通用电子制造执行系统(MES)

​简介:系统参考西门子MOM智能制造Opcenter工业软件制造执行系统Camstar电子套件人机料法环数据建模业务对象和车间生产执行事务逻辑,采用面向对象分层设计与C#编程开发:包含电子制造企业人机料法环业务数据建模实体对象,数据实体持久化映射,数据工厂会话配置,车间生产服务…

物料需求波动大、生产计划变化频繁?一文教你用工厂ERP系统MRP精确计算生产物料!

今天咱们来聊一聊一个大多数工厂都会遇到的问题: 物料需求波动大 和 生产计划变化频繁 。 这些问题可能让你在生产过程中经常“踩雷”,比如物料没采购够,生产停工; 或者物料买多了,库存积压,浪费了钱。有没有办法避免这些问题呢? 答案是: 有 !那就是通过工厂的 ERP系统…

docker使用GPU总结

在docker容器中使用显卡 一 docker19.03以前的事情 1.1 指定显卡硬件名 最初的容器中使用显卡,需要指定硬件名。经历了两种方式使用lxc驱动程序运行docker守护进程,以便能够修改配置并让容器访问显卡设备(非常麻烦,参考链接中最久远的回答)Docker 0.9中放弃了lxc作为默认执…

掌握 K8s Pod 基础应用 (二)

Pod生命周期 我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期,它主要包含下面的过程:pod创建过程运行初始化容器(init container)过程运行主容器(main container)容器启动后钩子(post start)、容器终止前钩子(pre stop)容器的存活性探测(liveness prob…

叉车人员防撞报警系统

叉车人员防撞报警系统采用机器视觉图像感知技术,通过人工智能深度学习技术,对行人和车辆的精确检测,叉车人员防撞报警系统实现对人体和车辆检测分析识别,在机器视觉图像景中,通过特征识别算法建立人体和车辆图像模型,完成自动识别目标,并能以视觉图像智能分析精确区分干…

课堂在线点名助手

适合老师上课随机提问学生的小工具。前情概要 为提高程序的普适性,学生姓名用学号代替。 在线点卯在线提问点名助手body0 { font-family: Arial, sans-serif; background-image: url(https://img2024.cnblogs.com/blog/992978/202503/992978-20250324092106498-1518746661.jpg…