外观
MariaDB Galera Cluster 特有故障
Galera Cluster 是 MariaDB 提供的高可用性集群解决方案,它基于同步复制和多主架构,提供了高可用性、数据一致性和易于管理的特点。然而,Galera Cluster 也存在一些特有的故障类型,如脑裂、网络分区、节点故障、复制冲突等。本文将详细介绍 Galera Cluster 特有故障的诊断、处理和预防方法,帮助 DBA 快速定位和解决 Galera Cluster 故障,提高集群的可用性和可靠性。
Galera Cluster 特有故障概述
Galera Cluster 架构回顾
Galera Cluster 是一个基于同步复制的多主集群,主要由以下组件组成:
- Galera 复制插件:实现节点间的同步复制
- wsrep API:提供复制接口,连接数据库和 Galera 复制插件
- Group Communication System (GCS):处理节点间的通信和成员管理
- State Snapshot Transfer (SST):处理节点加入集群时的数据同步
- Incremental State Transfer (IST):处理节点短期离线后的增量数据同步
特有故障类型
- 脑裂:集群分裂成多个独立的子集群,每个子集群都认为自己是唯一的活动集群
- 网络分区:由于网络故障,集群中的节点无法正常通信
- 节点故障:单个节点崩溃或失去连接
- 复制冲突:多个节点同时修改同一数据,导致复制冲突
- SST/IST 失败:节点加入集群时的数据同步失败
- Flow Control 阻塞:由于节点间复制延迟,导致 Flow Control 机制触发,阻塞写操作
- 集群冻结:整个集群无法处理写操作
- 节点不一致:集群中的节点数据不一致
故障影响
- 服务中断:部分或全部节点无法提供服务
- 数据不一致:节点间数据不一致,影响数据完整性
- 集群不可用:整个集群无法处理写操作
- 恢复时间长:故障恢复可能需要较长时间
- 业务影响:导致业务系统无法正常运行
版本差异
不同 MariaDB Galera Cluster 版本在故障处理方面存在一些差异:
- MariaDB 5.5 Galera:支持基本的 Galera 功能
- MariaDB 10.0 Galera:增强了 Galera 的性能和稳定性
- MariaDB 10.1 Galera:引入了更多的监控指标和故障检测机制
- MariaDB 10.2 Galera:优化了 SST/IST 过程,提高了同步效率
- MariaDB 10.3 Galera:增强了脑裂检测和处理机制
- MariaDB 10.4 Galera:优化了 Flow Control 机制,减少了阻塞
- MariaDB 10.5 Galera:提供了更详细的故障日志和诊断信息
常见 Galera Cluster 特有故障
故障一:脑裂
问题描述:脑裂是 Galera Cluster 中最严重的故障之一,当集群中的节点无法正常通信时,集群可能分裂成多个独立的子集群,每个子集群都认为自己是唯一的活动集群。
症状:
- 集群分裂成多个子集群
- 不同子集群中的节点状态不一致
- 客户端连接到不同子集群可能读取到不同的数据
- 错误日志中出现 "partition detected" 或 "conflict detected" 信息
产生原因:
- 网络故障导致节点间通信中断
- 节点负载过高,无法处理 GCS 消息
- 防火墙配置错误,阻止了 Galera 端口通信
- 节点时钟不同步
诊断方法:
- 使用
SHOW STATUS LIKE 'wsrep_cluster_size'查看每个节点的集群大小 - 使用
SHOW STATUS LIKE 'wsrep_cluster_status'查看每个节点的集群状态 - 使用
SHOW STATUS LIKE 'wsrep_incoming_addresses'查看每个节点感知到的其他节点 - 检查网络连接和防火墙配置
- 查看 Galera 日志,寻找脑裂相关的错误信息
处理方法:
紧急处理:
- 立即停止所有子集群的写操作
- 确定包含大多数节点的子集群
- 关闭其他子集群中的节点
- 修复网络故障
- 逐步将关闭的节点重新加入集群
长期处理:
- 配置
pc.weight参数,设置节点权重 - 启用
pc.ignore_quorum参数,避免脑裂 - 配置外部脑裂检测机制,如 Corosync 或 Pacemaker
- 加强网络监控,及时发现网络故障
- 配置
故障二:网络分区
问题描述:网络分区是指集群中的节点由于网络故障无法正常通信,但尚未导致脑裂。
症状:
- 部分节点无法通信
wsrep_cluster_size减少- 错误日志中出现 "connection closed" 或 "timeout" 信息
- Flow Control 机制可能触发,阻塞写操作
产生原因:
- 网络延迟或抖动
- 网络设备故障,如交换机、路由器故障
- 网络带宽不足
- 防火墙规则变更
诊断方法:
- 使用
SHOW STATUS LIKE 'wsrep_local_state_comment'查看节点状态 - 使用
SHOW STATUS LIKE 'wsrep_connected'查看节点连接状态 - 使用
SHOW STATUS LIKE 'wsrep_ready'查看节点是否就绪 - 测试节点间的网络连接,如使用
ping或telnet命令 - 查看 Galera 日志,寻找网络相关的错误信息
处理方法:
紧急处理:
- 检查网络连接,修复网络故障
- 重启无法通信的节点
- 检查防火墙配置,确保 Galera 端口开放
长期处理:
- 使用冗余网络,如双网卡绑定
- 优化网络配置,减少网络延迟
- 增加网络带宽
- 配置网络监控,及时发现网络故障
故障三:复制冲突
问题描述:复制冲突是指多个节点同时修改同一数据,导致 Galera 复制过程中出现冲突。
症状:
- 错误日志中出现 "repl conflict" 或 "certification failed" 信息
wsrep_local_cert_failures状态变量增加- 事务被回滚,客户端收到错误信息
- 节点间数据可能不一致
产生原因:
- 应用程序设计不当,允许多个节点同时修改同一数据
- 没有使用合适的隔离级别
- 自动递增主键冲突
- 外键约束冲突
诊断方法:
- 使用
SHOW STATUS LIKE 'wsrep_local_cert_failures'查看冲突次数 - 查看错误日志,寻找冲突相关的错误信息
- 使用
SHOW VARIABLES LIKE 'wsrep_debug'启用调试模式,获取更详细的冲突信息 - 分析应用程序代码,寻找可能导致冲突的逻辑
处理方法:
紧急处理:
- 修复导致冲突的数据
- 检查节点间数据一致性
- 重启节点,重新同步数据
长期处理:
- 优化应用程序设计,避免多个节点同时修改同一数据
- 使用合适的隔离级别,如 REPEATABLE READ
- 配置
wsrep_auto_increment_control参数,避免自动递增主键冲突 - 使用
wsrep_sync_wait参数,确保数据一致性 - 设计合理的数据分片策略,将不同的数据分配到不同的节点
故障四:SST/IST 失败
问题描述:SST (State Snapshot Transfer) 和 IST (Incremental State Transfer) 是 Galera Cluster 用于节点加入或恢复时的数据同步机制,SST/IST 失败会导致节点无法加入或恢复。
症状:
- 节点无法加入集群
- 错误日志中出现 "SST failed" 或 "IST failed" 信息
wsrep_sst_method相关的错误信息- 节点状态为
Joiner或Donor,但无法完成同步
产生原因:
- 网络带宽不足,导致 SST 超时
- 捐赠节点负载过高,无法完成 SST
- SST 方法配置错误,如使用了不支持的 SST 方法
- 防火墙阻止了 SST 端口通信
- 数据文件损坏,导致 SST 失败
诊断方法:
- 查看错误日志,寻找 SST/IST 相关的错误信息
- 检查 SST 方法配置,确保使用了合适的 SST 方法
- 测试节点间的网络带宽
- 检查捐赠节点的负载情况
- 检查防火墙配置,确保 SST 端口开放
处理方法:
紧急处理:
- 重启无法加入的节点
- 更换 SST 方法,如从
rsync改为xtrabackup - 增加 SST 超时时间,如修改
wsrep_sst_timeout参数 - 手动备份数据,恢复到无法加入的节点
长期处理:
- 优化网络配置,增加网络带宽
- 配置合适的 SST 方法,如使用
xtrabackup提高 SST 效率 - 配置
wsrep_sst_donor参数,指定捐赠节点 - 监控捐赠节点的负载,避免负载过高
- 定期检查数据文件完整性,避免数据损坏
故障五:Flow Control 阻塞
问题描述:Flow Control 是 Galera Cluster 用于处理节点间复制延迟的机制,当某个节点无法及时处理复制事件时,会触发 Flow Control,阻塞其他节点的写操作。
症状:
- 集群写性能下降
- 错误日志中出现 "Flow Control" 或 "paused" 信息
wsrep_flow_control_paused状态变量增加- 节点间复制延迟增加
产生原因:
- 某个节点负载过高,无法及时处理复制事件
- 网络延迟或带宽不足,导致复制延迟
- 大量写操作,超过了集群的处理能力
- 节点配置不当,如
innodb_buffer_pool_size设置过小
诊断方法:
- 使用
SHOW STATUS LIKE 'wsrep_flow_control_paused'查看 Flow Control 状态 - 使用
SHOW STATUS LIKE 'wsrep_local_recv_queue'查看接收队列长度 - 查看节点负载情况,寻找负载过高的节点
- 检查网络延迟和带宽
- 查看慢查询日志,寻找导致性能问题的查询
处理方法:
紧急处理:
- 优化导致负载过高的查询
- 增加节点资源,如 CPU、内存或磁盘
- 调整 Flow Control 配置,如修改
wsrep_slave_threads参数 - 暂时减少写操作,降低集群负载
长期处理:
- 优化节点配置,如增加
innodb_buffer_pool_size - 调整
wsrep_slave_threads参数,增加并行复制线程数 - 优化应用程序,减少写操作
- 考虑水平扩展,增加集群节点数量
- 监控 Flow Control 状态,及时发现问题
- 优化节点配置,如增加
故障六:节点状态异常
问题描述:节点状态异常是指节点的 wsrep_local_state_comment 状态异常,如 Joined、Donor、Desynced 等,导致节点无法正常提供服务。
症状:
- 节点无法处理写操作
wsrep_local_state_comment状态异常- 错误日志中出现 "state change" 或 "desynced" 信息
- 集群写性能下降
产生原因:
- 节点负载过高,无法及时处理复制事件
- 网络延迟,导致节点与集群不同步
- 数据文件损坏,导致节点无法正常运行
- 节点配置不当,如
wsrep_slave_threads设置过小
诊断方法:
- 使用
SHOW STATUS LIKE 'wsrep_local_state_comment'查看节点状态 - 查看错误日志,寻找状态变更相关的错误信息
- 检查节点负载情况
- 检查网络延迟和带宽
- 检查数据文件完整性
处理方法:
紧急处理:
- 重启状态异常的节点
- 检查并修复数据文件损坏
- 调整节点配置,如增加
wsrep_slave_threads - 修复网络故障
长期处理:
- 优化节点配置,提高节点性能
- 加强节点监控,及时发现状态异常
- 配置
wsrep_desync参数,允许节点暂时脱离集群,处理负载 - 定期检查数据文件完整性
- 优化应用程序,减少节点负载
Galera Cluster 故障诊断
使用 Galera 状态变量
Galera Cluster 提供了丰富的状态变量,可以用于诊断故障:
sql
-- 查看集群状态
SHOW STATUS LIKE 'wsrep_cluster%';
-- 查看节点状态
SHOW STATUS LIKE 'wsrep_local%';
-- 查看复制状态
SHOW STATUS LIKE 'wsrep_flow_control%';
SHOW STATUS LIKE 'wsrep_received%';
SHOW STATUS LIKE 'wsrep_sent%';
-- 查看冲突和错误
SHOW STATUS LIKE 'wsrep_local_cert_failures';
SHOW STATUS LIKE 'wsrep_last_committed';
SHOW STATUS LIKE 'wsrep_apply_oooe';使用 Galera 日志
Galera 日志包含了详细的集群信息和错误日志,默认位置为 /var/log/mysql/galera.log。可以通过以下命令查看 Galera 日志:
bash
# 查看 Galera 日志最后 100 行
tail -n 100 /var/log/mysql/galera.log
# 搜索特定关键词
grep -i "error\|warning\|critical\|partition\|conflict" /var/log/mysql/galera.log
# 查看最近的状态变更
grep -n "state change" /var/log/mysql/galera.log使用外部工具
- Galera Cluster Manager (GCM):提供了 Galera Cluster 的监控和管理功能
- Percona Monitoring and Management (PMM):提供了 Galera Cluster 的监控面板
- Prometheus + Grafana:通过 MariaDB Exporter 收集 Galera 指标,使用 Grafana 可视化
- ClusterControl:提供了 Galera Cluster 的监控、管理和自动化运维功能
常见故障诊断流程
检查节点状态:
sqlSHOW STATUS LIKE 'wsrep_local_state_comment'; SHOW STATUS LIKE 'wsrep_connected'; SHOW STATUS LIKE 'wsrep_ready';检查集群状态:
sqlSHOW STATUS LIKE 'wsrep_cluster_size'; SHOW STATUS LIKE 'wsrep_cluster_status'; SHOW STATUS LIKE 'wsrep_incoming_addresses';检查复制状态:
sqlSHOW STATUS LIKE 'wsrep_flow_control_paused'; SHOW STATUS LIKE 'wsrep_local_recv_queue'; SHOW STATUS LIKE 'wsrep_local_send_queue';检查冲突和错误:
sqlSHOW STATUS LIKE 'wsrep_local_cert_failures'; SHOW STATUS LIKE 'wsrep_last_committed';查看日志:
- 检查 MariaDB 错误日志
- 检查 Galera 日志
- 检查系统日志
检查网络和硬件:
- 测试节点间的网络连接
- 检查节点负载情况
- 检查磁盘和内存使用情况
Galera Cluster 故障预防
网络层面
使用冗余网络:
- 配置双网卡绑定,提高网络可靠性
- 使用不同的网络供应商,避免单点故障
- 配置 VLAN,隔离 Galera 通信流量
优化网络配置:
- 增加网络带宽,满足 Galera 同步复制的需求
- 优化网络延迟,减少节点间通信时间
- 配置 QoS,确保 Galera 流量的优先级
加强网络监控:
- 监控网络延迟和带宽使用情况
- 监控网络设备状态,如交换机、路由器
- 设置网络故障告警,及时发现网络问题
配置层面
优化 Galera 配置:
ini[mysqld] # 启用 Galera 复制插件 wsrep_on = ON wsrep_provider = /usr/lib/galera/libgalera_smm.so # 集群名称 wsrep_cluster_name = "my_galera_cluster" # 集群地址 wsrep_cluster_address = "gcomm://node1,node2,node3" # 节点名称 wsrep_node_name = "node1" # 节点地址 wsrep_node_address = "node1.example.com:4567" # SST 方法 wsrep_sst_method = xtrabackup # 并行复制线程数 wsrep_slave_threads = 8 # Flow Control 配置 wsrep_flow_control_mode = AUTO # 节点权重 pc.weight = 1优化 InnoDB 配置:
ini[mysqld] # 启用 InnoDB default_storage_engine = InnoDB # 配置 InnoDB 缓冲池大小 innodb_buffer_pool_size = 4G # 配置 InnoDB 日志文件大小 innodb_log_file_size = 1G # 配置 InnoDB 刷新策略 innodb_flush_log_at_trx_commit = 2 # 禁用 InnoDB 双写缓冲(可选,提高性能) # innodb_doublewrite = 0配置脑裂预防机制:
ini[mysqld] # 节点权重 pc.weight = 1 # 忽略 quorum(谨慎使用) # pc.ignore_quorum = 1 # 配置捐赠节点 wsrep_sst_donor = "node1,node2"
运维层面
建立完善的监控体系:
- 监控 Galera Cluster 状态变量
- 监控节点负载和资源使用情况
- 监控网络状态和延迟
- 设置合理的告警阈值,及时发现故障
定期维护集群:
- 定期检查节点状态和数据一致性
- 定期备份集群数据
- 定期升级 Galera Cluster 版本
- 定期测试故障恢复流程
制定故障恢复计划:
- 制定详细的故障恢复流程
- 定期进行故障恢复演练
- 建立应急响应团队,明确责任分工
- 建立与业务部门的沟通机制
加强变更管理:
- 所有集群变更都要经过审批
- 变更前进行充分的测试
- 制定回滚计划,确保变更可以回滚
- 变更后进行验证,确保集群正常运行
Galera Cluster 故障案例分析
案例一:脑裂导致的数据不一致
问题描述: 某公司的 Galera Cluster 由于网络故障导致脑裂,集群分裂成两个子集群,每个子集群都处理了部分写操作,导致数据不一致。
诊断过程:
- 查看节点状态,发现集群分裂成两个子集群,一个包含 2 个节点,另一个包含 1 个节点
- 查看错误日志,发现 "partition detected" 信息
- 检查网络连接,发现交换机故障导致节点间通信中断
- 对比两个子集群的数据,发现数据不一致
处理方法:
- 立即停止所有子集群的写操作
- 确定包含 2 个节点的子集群为活动集群
- 关闭包含 1 个节点的子集群
- 修复交换机故障
- 使用
xtrabackup从活动集群的节点创建备份 - 将备份恢复到关闭的节点
- 启动节点,使其重新加入集群
- 验证所有节点的数据一致性
优化结果:
- 集群恢复正常运行
- 数据一致性得到保证
- 配置了双网卡绑定,提高了网络可靠性
- 启用了外部脑裂检测机制,避免类似故障再次发生
案例二:复制冲突导致的事务回滚
问题描述: 某电商网站的 Galera Cluster 频繁出现复制冲突,导致事务回滚,影响用户体验。
诊断过程:
- 查看
wsrep_local_cert_failures状态变量,发现冲突次数较多 - 查看错误日志,发现 "certification failed" 信息
- 分析应用程序代码,发现多个节点同时修改同一订单数据
- 检查隔离级别,发现使用的是
READ-COMMITTED隔离级别
处理方法:
- 优化应用程序设计,使用分布式锁避免多个节点同时修改同一数据
- 将隔离级别调整为
REPEATABLE-READ - 配置
wsrep_sync_wait = 1,确保数据一致性 - 设计数据分片策略,将不同的订单分配到不同的节点
优化结果:
- 复制冲突次数减少了 90%
- 事务回滚率显著降低
- 用户体验得到改善
- 系统性能有所提升
案例三:Flow Control 阻塞导致的性能下降
问题描述: 某公司的 Galera Cluster 在高峰期频繁触发 Flow Control,导致写性能下降,影响业务系统。
诊断过程:
- 查看
wsrep_flow_control_paused状态变量,发现 Flow Control 暂停时间较长 - 查看
wsrep_local_recv_queue,发现接收队列长度较大 - 检查节点负载,发现某个节点的 CPU 使用率达到 100%
- 查看慢查询日志,发现大量复杂的写查询
处理方法:
- 优化导致负载过高的查询
- 增加节点的 CPU 核心数
- 调整
wsrep_slave_threads从 4 增加到 16 - 配置
wsrep_flow_control_mode = AUTO - 优化应用程序,将部分写操作转移到低峰期
优化结果:
- Flow Control 暂停时间减少了 80%
- 写性能提升了 50%
- 高峰期系统稳定性显著提高
- 节点负载更加均衡
FAQ
Q1: 如何判断 Galera Cluster 是否发生脑裂?
A1: 可以通过以下方法判断:
- 查看每个节点的
wsrep_cluster_size,如果不同节点的集群大小不同,可能发生了脑裂 - 查看每个节点的
wsrep_incoming_addresses,如果不同节点感知到的其他节点不同,可能发生了脑裂 - 查看 Galera 日志,寻找 "partition detected" 或 "conflict detected" 信息
- 对比不同节点的数据,如果数据不一致,可能发生了脑裂
Q2: 如何处理 Galera Cluster 脑裂?
A2: 可以采取以下步骤处理:
- 立即停止所有子集群的写操作
- 确定包含大多数节点的子集群为活动集群
- 关闭其他子集群中的节点
- 修复网络故障
- 逐步将关闭的节点重新加入集群
- 验证所有节点的数据一致性
Q3: 如何避免 Galera Cluster 复制冲突?
A3: 可以采取以下措施避免:
- 优化应用程序设计,避免多个节点同时修改同一数据
- 使用合适的隔离级别,如
REPEATABLE-READ - 配置
wsrep_sync_wait参数,确保数据一致性 - 使用分布式锁,避免并发修改
- 设计合理的数据分片策略,将不同的数据分配到不同的节点
Q4: 如何优化 Galera Cluster 的 SST 过程?
A4: 可以采取以下措施优化:
- 使用高效的 SST 方法,如
xtrabackup或mariabackup - 增加 SST 超时时间,如修改
wsrep_sst_timeout参数 - 配置
wsrep_sst_donor参数,指定性能较好的节点作为捐赠节点 - 增加网络带宽,满足 SST 同步的需求
- 避免在高峰期进行 SST 操作
Q5: 如何处理 Galera Cluster 中的节点故障?
A5: 可以采取以下步骤处理:
- 检查节点故障原因,如硬件故障、软件错误等
- 如果是临时故障,重启节点使其重新加入集群
- 如果是硬件故障,更换硬件并重新加入集群
- 如果数据文件损坏,使用备份恢复数据
- 监控集群状态,确保所有节点正常同步
Q6: 如何监控 Galera Cluster 的状态?
A6: 可以使用以下工具监控:
- Galera 状态变量:通过
SHOW STATUS命令查看 - Galera 日志:查看
/var/log/mysql/galera.log - 外部监控工具:如 Prometheus + Grafana、Percona PMM、ClusterControl 等
- 自定义监控脚本:编写脚本监控 Galera 状态变量,设置告警
Q7: Galera Cluster 和传统主从复制的故障处理有什么区别?
A7: Galera Cluster 和传统主从复制的故障处理存在以下区别:
- Galera Cluster 是多主架构,没有主从之分,故障处理更加复杂
- Galera Cluster 可能发生脑裂,需要额外的脑裂检测和处理机制
- Galera Cluster 使用同步复制,故障恢复时间较短
- Galera Cluster 节点加入或恢复时需要进行 SST/IST 同步
- Galera Cluster 提供了更丰富的状态变量和日志,便于故障诊断
Q8: 如何升级 Galera Cluster 版本?
A8: 可以采取以下步骤升级:
- 备份所有节点的数据
- 逐个节点升级,先升级非捐赠节点
- 升级每个节点时,先停止节点,升级软件包,然后启动节点
- 等待节点重新加入集群,确保同步完成
- 验证集群状态,确保所有节点正常运行
- 升级完成后,运行功能测试,确保业务正常
附录:Galera Cluster 常用命令
集群管理命令
sql
-- 查看集群状态
SHOW STATUS LIKE 'wsrep_cluster%';
-- 查看节点状态
SHOW STATUS LIKE 'wsrep_local%';
-- 查看复制状态
SHOW STATUS LIKE 'wsrep_flow_control%';
-- 查看冲突和错误
SHOW STATUS LIKE 'wsrep_local_cert_failures';
-- 查看 Galera 配置
SHOW VARIABLES LIKE 'wsrep%';
-- 手动触发 SST
SET GLOBAL wsrep_provider_options='pc.bootstrap=true';节点管理命令
bash
# 启动 Galera 集群(第一个节点)
mysqld_safe --wsrep-new-cluster &
# 启动 Galera 节点(加入现有集群)
mysqld_safe &
# 停止 Galera 节点
mysqladmin -u root -p shutdown
# 查看 Galera 节点状态
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_local_state_comment'";日志查看命令
bash
# 查看 MariaDB 错误日志
tail -n 100 /var/log/mariadb/mariadb.log
# 查看 Galera 日志
tail -n 100 /var/log/mysql/galera.log
# 搜索 Galera 错误信息
grep -i "error\|warning\|critical" /var/log/mysql/galera.log网络测试命令
bash
# 测试节点间网络延迟
ping node2.example.com
# 测试 Galera 端口连通性
telnet node2.example.com 4567
nc -zv node2.example.com 4567
# 测试 SST 端口连通性
telnet node2.example.com 4444
# 测试 IST 端口连通性
telnet node2.example.com 4568