在 PostgreSQL 高可用性部署中,结合 PostgreSQL 主从复制 和 Keepalived 来实现自动故障切换与主从冗余是一个常见且有效的方案。此方案的目标是确保 PostgreSQL 数据库的高可用性,能够在主节点故障时自动切换到备用节点,并确保数据库继续提供服务。
方案架构
PostgreSQL 主从复制:主节点负责处理写请求,从节点同步主节点的数据,并处理只读请求。
Keepalived:负责管理虚拟 IP(VIP)。当主节点发生故障时,VIP 会自动漂移到从节点,实现自动故障切换。
自动切换:当主节点不可用时,Keepalived 会将虚拟 IP 漂移到从节点,并通过触发文件(trigger_file)使从节点提升为可写主节点。
关键要素
虚拟 IP(VIP):由 Keepalived 管理,始终指向当前的主节点。主节点故障时,VIP 会漂移到从节点。
触发文件(trigger_file):当主节点故障并且 VIP 漂移到从节点时,通过创建 trigger_file 文件,PostgreSQL 从节点会自动提升为主节点并开始接受写操作。
健康检查:Keepalived 会定期检查主节点的健康状态,当主节点不可用时,自动将 VIP 漂移到从节点,并触发从节点提升为主节点。
1.1 主节点配置
编辑 PostgreSQL 主节点的配置文件 postgresql.conf:
sudo vi /etc/postgresql/
配置以下参数以启用流复制和提高性能:
wal_level = replica max_wal_senders = 3 max_replication_slots = 3 max_wal_size = 1GB hot_standby = on listen_addresses = '*'
编辑 pg_hba.conf 文件,允许从节点进行复制连接:
sudo vi /etc/postgresql/
添加以下条目:
host replication replication
创建复制角色(用于主从复制):
CREATE ROLE replication WITH REPLICATION LOGIN PASSWORD 'replication_password';
1.2 从节点配置
停止从节点的 PostgreSQL 服务:
sudo systemctl stop postgresql
使用 pg_basebackup 从主节点备份数据:
pg_basebackup -h
在从节点的 postgresql.conf 中启用热备份:
sudo vi /etc/postgresql/
添加以下配置:
hot_standby = on
在从节点上创建 recovery.conf 文件(在 PGDATA 目录下):
sudo vi /var/lib/postgresql/data/recovery.conf
配置如下:
standby_mode = 'on' primary_conninfo = 'host=
trigger_file:创建该文件后,从节点会被提升为主节点。
2.1 安装 Keepalived
在主从节点上安装 Keepalived:
sudo apt-get install keepalived
2.2 配置主节点的 Keepalived
编辑 /etc/keepalived/keepalived.conf 文件,配置主节点的 Keepalived:
sudo vi /etc/keepalived/keepalived.conf
主节点配置如下:
global_defs { router_id MASTER } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 101 advert_int 1 virtual_ipaddress { 192.168.x.x # 虚拟 IP 地址 } track_script { chk_postgresql } # 监控 PostgreSQL 是否正常 vrrp_script chk_postgresql { script "pg_isready -h 127.0.0.1 -p 5432" interval 2 weight 2 } }
state MASTER:主节点状态。
priority 101:主节点的优先级,必须高于从节点。
virtual_ipaddress:虚拟 IP 地址,客户端通过该 IP 连接数据库。
2.3 配置从节点的 Keepalived
在从节点的 /etc/keepalived/keepalived.conf 中配置如下:
sudo vi /etc/keepalived/keepalived.conf
从节点配置如下:
global_defs { router_id BACKUP } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 100 advert_int 1 virtual_ipaddress { 192.168.x.x # 虚拟 IP 地址,与主节点相同 } track_script { chk_postgresql } # 监控 PostgreSQL 是否正常 vrrp_script chk_postgresql { script "pg_isready -h 127.0.0.1 -p 5432" interval 2 weight 2 } }
state BACKUP:从节点的状态。
priority 100:从节点的优先级,低于主节点。
2.4 创建脚本来自动创建 trigger_file
在从节点上创建一个脚本,当 VIP 漂移到从节点时,自动创建 trigger_file 文件,从而触发从节点的提升。
创建 /etc/keepalived/create_trigger_file.sh 文件:
sudo vi /etc/keepalived/create_trigger_file.sh
内容如下:
#!/bin/bash if [ ! -f /tmp/promote ]; then touch /tmp/promote echo "Trigger file created. Promoting to master." else echo "Trigger file already exists. No action needed." fi
设置脚本可执行权限:
sudo chmod +x /etc/keepalived/create_trigger_file.sh
2.5 修改 Keepalived 配置,添加触发文件脚本
在从节点的 keepalived.conf 文件中添加 vrrp_script 来执行 create_trigger_file.sh 脚本:
vrrp_script create_trigger_file { script "/etc/keepalived/create_trigger_file.sh" interval 2 weight 2 }
这样,当 VIP 漂移到从节点时,create_trigger_file.sh 脚本会被执行,从节点将被提升为主节点。
启动 PostgreSQL 服务:
sudo systemctl start postgresql
启动 Keepalived 服务:
sudo systemctl start keepalived
启用 Keepalived 和 PostgreSQL 服务:
sudo systemctl enable keepalived sudo systemctl enable postgresql
在主节点上查看虚拟 IP 是否绑定:
ip a show eth0
确保虚拟 IP 被绑定到主节点的网络接口上。
模拟主节点宕机(停止主节点的 PostgreSQL 服务):
sudo systemctl stop postgresql
查看 从节点 上是否自动接管了虚拟 IP,并且从节点已成为主节点:
ip a show eth0
如果从节点接管了 VIP,并且在 /tmp/promote 文件中找到了 trigger_file,则说明从节点已成功提升为主节点。
在从节点(现在是主节点)上执行写操作,验证是否可写:
INSERT INTO test_table (data) VALUES ('test data');
当原主节点恢复时,可以通过流复制将数据同步到主节点。原主节点恢复后,将作为新的从节点加入集群,继续同步数据。
总结
该方案通过结合 PostgreSQL 主从复制 和 Keepalived 的虚拟 IP 迁移与自动故障切换机制,实现了 PostgreSQL 的高可用性部署。关键点在于:
使用 Keepalived 管理虚拟 IP,确保主节点故障时,虚拟 IP 自动漂移到从节点。
利用 trigger_file 机制,在从节点接管虚拟 IP 后自动将其提升为主节点。
配置健康检查脚本以确保在主节点故障时,从节点能顺利接管。
通过这个方案,可以在主节点发生故障时,确保 PostgreSQL 数据库的持续服务,避免长时间的停机。