Skip to content

PostgreSQL 脑裂预防

脑裂(Split Brain)是 PostgreSQL 高可用集群中的严重问题,指集群中出现多个主节点,导致数据不一致。脑裂会造成数据丢失、业务混乱,甚至导致整个系统崩溃。

脑裂概述

什么是脑裂

脑裂是指在高可用集群中,由于网络分区或节点故障,集群被分割成多个独立的子集群,每个子集群都认为自己是唯一的主集群,从而选举出多个主节点。

脑裂的危害

  • 数据不一致:多个主节点接收写入,导致数据冲突
  • 数据丢失:解决脑裂时可能需要丢弃部分数据
  • 业务中断:应用无法确定连接哪个主节点
  • 恢复复杂:需要手动干预恢复集群
  • 系统可靠性下降:破坏高可用架构的信任基础

脑裂的原因

  • 网络分区:主备节点之间网络通信中断
  • 节点故障:主节点或备节点硬件故障
  • 资源耗尽:主节点 CPU、内存或磁盘耗尽,无法响应心跳
  • 时钟不同步:节点间时钟偏差过大,导致心跳超时
  • 配置错误:高可用软件配置不当

脑裂预防机制

心跳机制优化

  • 多路径心跳:使用多条网络路径发送心跳
  • 合理的心跳超时时间:根据网络延迟调整,避免误判
  • 心跳频率:适当提高心跳频率,加快故障检测
  • 心跳认证:确保心跳消息的真实性

仲裁机制

  • 票数机制:集群决策需要超过半数节点同意

    • 奇数节点数:3、5、7个节点,避免平票
    • 投票规则:超过半数节点同意才能选举主节点
  • 外部仲裁:引入外部组件进行仲裁

    • etcd/consul:分布式一致性存储
    • Zookeeper:分布式协调服务
    • 专用仲裁节点:独立的硬件或虚拟机

STONITH(Shoot The Other Node In The Head)

  • 自动关闭被隔离的主节点
  • 确保只有一个主节点存活
  • 支持多种实现方式:IPMI、iLO、SSH、外部电源管理

fencing 机制

  • 网络fencing:隔离问题节点的网络访问
  • 存储fencing:防止问题节点访问共享存储
  • 进程fencing:终止问题节点的PostgreSQL进程

不同高可用方案的脑裂预防

repmgr 脑裂预防

配置参数

ini
# 配置文件:repmgr.conf
failover=automatic
promote_command='repmgr standby promote -f /etc/repmgr.conf'
follow_command='repmgr standby follow -f /etc/repmgr.conf'

预防机制

  • 基于见证节点(Witness)的仲裁
  • 严格的主备角色管理
  • 复制状态检查

Patroni 脑裂预防

配置参数

yaml
# 配置文件:patroni.yml
consul:
  host: consul:8500
retry_timeout: 10
maximum_lag_on_failover: 1048576

预防机制

  • 基于分布式一致性存储(etcd/consul/ZooKeeper)的仲裁
  • 严格的 leader 选举机制
  • 自动 fencing 功能
  • 复制延迟检查

pg_auto_failover 脑裂预防

配置参数

ini
# 配置文件:pg_autoctl.cfg
formation: default
pgdata: /var/lib/postgresql/15/main

预防机制

  • 基于 PostgreSQL 内置复制机制
  • 控制器节点仲裁
  • 自动故障检测和切换
  • 节点状态一致性检查

pgpool-II 脑裂预防

配置参数

ini
# 配置文件:pgpool.conf
sr_check_period = 3
sr_check_user = 'repmgr'
sr_check_password = 'repmgr'
sr_check_database = 'repmgr'

预防机制

  • 健康检查和状态监控
  • 主节点自动检测
  • 连接路由控制
  • 复制状态验证

脑裂检测和处理

脑裂检测

1. 集群状态检查

bash
# repmgr 集群状态检查
repmgr cluster show

# Patroni 集群状态检查
patronictl list

# pg_auto_failover 状态检查
pg_autoctl show state

2. 日志分析

检查 PostgreSQL 日志和高可用软件日志,寻找脑裂相关信息:

bash
tail -f /var/log/postgresql/postgresql-15-main.log
grep -i "split brain" /var/log/patroni/patroni.log

3. 监控告警

配置监控系统,当检测到多个主节点时触发告警:

  • Prometheus + Grafana:配置多主节点告警规则
  • Zabbix:创建触发器检测多主节点
  • 自定义脚本:定期检查集群状态

脑裂处理

1. 紧急处理步骤

  • 立即停止所有节点的写入操作
  • 断开应用与数据库的连接
  • 确定真正的主节点(通常是最新数据的节点)
  • 关闭其他伪主节点
  • 重建备节点
  • 恢复集群正常状态

2. 数据恢复

  • 比较各节点数据,确定最新数据
  • 使用 pg_dump/pg_restore 恢复数据
  • 或使用 pg_basebackup 重建备节点
  • 验证数据一致性

3. 预防措施改进

  • 优化网络架构,提高网络可靠性
  • 调整心跳超时时间
  • 增加仲裁节点
  • 配置自动 fencing
  • 加强监控告警

脑裂预防最佳实践

1. 集群架构设计

  • 使用奇数节点数(3、5、7个节点)
  • 分离心跳网络和业务网络
  • 部署专用仲裁节点
  • 考虑跨可用区部署

2. 配置优化

  • 设置合理的心跳超时时间(一般为网络延迟的5-10倍)
  • 配置自动 fencing 功能
  • 启用复制延迟检查
  • 配置严格的 leader 选举规则

3. 监控告警

  • 配置多主节点告警
  • 监控网络连通性
  • 监控节点状态变化
  • 配置心跳超时告警

4. 定期演练

  • 模拟网络分区场景
  • 测试脑裂预防机制
  • 演练脑裂处理流程
  • 验证数据一致性

5. 操作规范

  • 避免手动干预集群状态
  • 严格执行变更管理流程
  • 定期检查集群配置
  • 保持软件版本一致

版本差异

PostgreSQL 9.0+ 版本

  • 支持流式复制,提供更好的主备同步
  • repmgr 2.x+ 支持基本的脑裂预防

PostgreSQL 10+ 版本

  • 增强了复制功能,支持逻辑复制
  • Patroni 1.x+ 提供更完善的脑裂预防
  • 支持并行复制,减少复制延迟

PostgreSQL 12+ 版本

  • 改进了 WAL 日志管理,提高复制可靠性
  • 增强了监控视图,便于检测脑裂
  • 支持复制槽,防止 WAL 日志丢失

PostgreSQL 14+ 版本

  • 支持即时恢复(PITR),加快故障恢复
  • 增强了逻辑复制功能
  • 改进了自动 vacuum,减少资源占用

常见问题与解决方案

1. 网络分区导致脑裂

解决方案:

  • 部署多路径网络
  • 配置网络冗余
  • 使用专用心跳网络
  • 增加网络监控

2. 心跳超时导致误判

解决方案:

  • 根据实际网络延迟调整心跳超时时间
  • 增加心跳频率
  • 配置多路径心跳
  • 优化网络性能

3. 仲裁节点故障

解决方案:

  • 部署多个仲裁节点
  • 使用分布式一致性存储(etcd/consul)
  • 定期检查仲裁节点状态
  • 配置仲裁节点监控

4. fencing 机制失效

解决方案:

  • 测试 fencing 功能定期
  • 配置多种 fencing 方式
  • 确保 fencing 权限正确
  • 监控 fencing 执行结果

通过合理的架构设计、配置优化和监控告警,可以有效预防 PostgreSQL 高可用集群中的脑裂问题,确保数据一致性和系统可靠性。