
1. 为什么是Galera Cluster而不是传统主从复制先说一个很现实的场景业务量一旦上来单台MariaDB撑不住读压力最常见的做法是搭主从复制主库负责写从库负责读。但传统主从有个让人头疼的问题——主库宕机了从库不会自动变成主库得人工介入用命令去提升还要考虑数据一致性搞不好就是几分钟甚至更长时间的业务中断。而Galera Cluster给出的方案是多主同步复制集群里任何一个节点都能读写任何一台挂了流量自动打到其他节点应用程序那边基本无感知。我最早接触Galera是因为一个项目业务对可用性要求比较高又不希望引入太重的中间件。对比了几种方案之后最终在MariaDB 10.6上做了三个节点的Galera Cluster。整套方案跑下来最大的感受是Galera的同步复制机制带来的好处很直接——数据在每个节点上都是完整一致的任何一个节点故障另一个节点随时可以顶上不需要像传统主从那样做额外的failover操作。Galera Cluster的核心优势有这几个多主同时读写所有节点对等不存在单点写瓶颈。同步复制机制事务要么在所有节点上提交要么全部回滚不会出现主从数据不一致。节点故障自动检测集群会自动把故障节点隔离出去剩余节点继续工作。扩展方便需要增加容量时加一个新节点就行加入过程自动完成数据同步。当然Galera也不是万金油。它对网络延迟比较敏感跨机房部署时需要谨慎评估而且所有节点都要能互通防火墙要放通相应的端口。另外它不适合超大事务和批量写入的场景因为同步复制会把事务同时推送到所有节点大事务会导致集群性能下降明显。我们当时真实的诉求很简单一套稳定、可靠、能自动故障切换的MariaDB集群方案并且尽量少依赖外部组件。MariaDB 10.6自带的Galera支持已经很成熟不需要额外安装独立补丁包直接装MariaDB-server和galera相关包就行这也是我选择这条技术路线的一个重要原因。需要特别说明的一点如果你的业务中写入非常密集比如大量短小事务Galera的性能表现其实相当好。但如果有类似一次性UPDATE几百万行的操作建议拆分事务或者换其他方案。这个限制来自同步复制的机制本身和版本关系不大。2. 部署前的关键思考节点规划、系统配置与同步机制的匹配部署一套Galera Cluster最忌拿到包就开始安装。我见过不少人在这一步跳进坑里安装过程看着顺利结果一启动集群就各种报错归根结底是前置条件没有准备好。2.1 节点规划与网络要求Galera集群至少需要3个节点这是为了在脑裂场景下能通过法定票数quorum选举出可用节点。两个节点当然也能组成集群但其中一个挂了之后剩下一个无法自证自己是多数派集群会进入不可用状态这在生产环境里是灾难。节点规划时要注意奇数节点是最基本的要求推荐生产环境使用3节点或5节点。各节点之间的网络最好是低延迟、高带宽的内网。Galera每个事务提交都会有几次网络交互延迟过高会直接影响写入性能。节点数量不要盲目追求多。5个节点虽然容错能力更强但每次提交的网络开销也会增多性能不如3节点。没有明显的高可用需求3节点是最优选择。我当时的配置是3个节点操作系统为CentOS系统IP规划大概是这样这里用模拟项目Y的节点IP演示节点主机名IP地址角色节点1db-node1192.168.10.11主节点初始引导节点2db-node2192.168.10.12普通节点节点3db-node3192.168.10.13普通节点2.2 防火墙端口Galera的通信方式Galera Cluster的节点间通信依赖4个关键端口防火墙放通这些端口是做集群部署的前提条件。具体包括端口作用3306MySQL/MariaDB服务端口用于客户端连接和节点间SST传输4567Galera Cluster节点间通信端口走的是UDP和TCP4568ISTIncremental State Transfer增量状态传输端口4444SSTState Snapshot Transfer全量状态快照传输端口使用mariabackup时常用放通防火墙的命令大致如下以firewalld为例firewall-cmd --permanent --add-port3306/tcp firewall-cmd --permanent --add-port4567/tcp firewall-cmd --permanent --add-port4567/udp firewall-cmd --permanent --add-port4568/tcp firewall-cmd --permanent --add-port4444/tcp firewall-cmd --reload如果节点之间还有额外的安全组规则需要放行记得一并处理好。这一步很基础但经常被忽略而且出现连接超时的报错时很多人不会第一时间想到是防火墙问题。提示SELinux也要注意如果处于Enforcing模式可能需要调整MariaDB相关的布尔值或者临时设置为Permissive模式再测试。排错时这两个因素往往比配置本身更折腾人。2.3 系统参数调优为同步复制做好准备Galera对系统环境有几个隐性的要求。第一是文件描述符限制第二是内存相关问题。MariaDB在运行过程中会打开大量文件建议在/etc/security/limits.conf中调整mysql soft nofile 65535 mysql hard nofile 65535 mysql soft nproc 65535 mysql hard nproc 65535内核参数方面建议优化网络缓冲区。Galera的gcomm传输层对网络缓冲区有一定需求可以调整如下cat /etc/sysctl.conf EOF net.core.somaxconn 65535 net.core.netdev_max_backlog 65535 net.ipv4.tcp_max_syn_backlog 65535 net.ipv4.tcp_fin_timeout 30 net.ipv4.tcp_tw_reuse 1 net.ipv4.tcp_tw_recycle 0 net.ipv4.ip_local_port_range 1024 65535 EOF sysctl -p这里有个容易被忽略的点IP转发不需要开启但网络流量较大的情况下尽量把网卡中断和队列长度调大避免tcp包在网络层排队。另外如果服务器时间不同步也要顺手配好NTP。Galera虽然没有在时间戳上做硬性校验但日志排查时时间一致会省很多事。swap也是一个考量因素。建议在部署前评估实例配置的内存如果物理内存充足把swap尽量调低甚至关闭。MariaDB在内存紧张时如果发生swap性能会断崖式下跌Galera节点之间的心跳和数据同步也会受到牵连。2.4 存储与SST方法选择会直接影响首次同步速度SST是Galera节点加入集群时用来做全量数据同步的机制。常用方法包括mysqldump、rsync、mariabackup三种。mysqldump逻辑备份方式通用性最强兼容性好但是速度慢而且需要先解析SQL再执行不适合大数据量。rsync物理文件拷贝速度较快但同步期间会阻塞数据目录的写入适合停机维护或数据量不算大的场景。mariabackup物理备份工具基于InnoDB的物理热备不停机完成同步对生产环境友好数据量大的时候首选。在MariaDB 10.6中mariabackup是官方推荐的SST工具。它在热备过程中通过复制数据文件的方式同步不阻塞业务写入能极大降低节点加入集群时的业务影响。我当时的写法是wsrep_sst_methodmariabackup使用mariabackup需要注意一点SST发起节点Joiner和提供数据的节点Donor都要安装mariabackup工具并且要有足够的临时磁盘空间来存放备份产生的文件。磁盘空间评估不足大集群同步到一半崩溃的案例不是没有。2.5 存储引擎与事务隔离级别的匹配Galera Cluster只支持InnoDB存储引擎这是一个硬性约束。部署之前要把所有业务表都改成InnoDB不然会出现无法写入的错误提示。Memory表、临时表以及系统表的特殊处理方式在Galera环境下都有特定的行为约束需要在设计阶段就考虑到。事务隔离级别方面Galera默认支持的事务隔离级别是REPEATABLE READ和READ COMMITTED。由于多节点同时写入可能产生冲突Galera在高并发写场景下建议使用READ COMMITTED能降低事务冲突的概率。这个配置更贴近真实的业务需求也会让整个集群在多主同时写入时更平滑。在MariaDB配置文件中需要明确设置transaction-isolation READ-COMMITTED binlog_format ROWbinlog_format必须使用ROW模式这是Galera强制要求的因为Galera的复制信息是通过解析行级binlog事件来广播的。如果设置为STATEMENT模式或者MIXED模式集群会拒绝启动。3. 一步步把集群拉起来安装、初始化引导与节点加入配置层面的准备做完就到了实际操作环节。下面用MariaDB 10.6在CentOS环境下的部署过程来做说明命令可以直接复制执行。3.1 安装MariaDB 10.6及Galera相关软件包三个节点都要安装这一步没有差别。首先配置MariaDB官方的软件源。可以直接使用官方提供的脚本或者手动写入repo文件。官方仓库配置方式比较推荐因为后续升级维护方便。curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | bash -s -- --mariadb-server-version10.6然后安装dnf install -y MariaDB-server MariaDB-client mariadb-backupGalera的实现是作为一个插件动态加载到MariaDB中的不再需要额外安装独立的galera包这也是10.6版本之后的便利之处。安装完成后可以检查一下相关文件是否存在ls /usr/lib64/galera/能看到类似libgalera_smm.so的文件就说明插件库已经就位。3.2 配置文件的核心参数逐一说明MariaDB的配置文件默认路径是/etc/my.cnf.d/建议单独创建一个galera.cnf文件来存放集群相关配置避免和默认配置混在一起。[mysqld] # 基础设置 server-id1 log-binmysql-bin binlog_formatROW transaction-isolationREAD-COMMITTED default-storage-engineInnoDB # Galera相关配置 wsrep_onON wsrep_provider/usr/lib64/galera/libgalera_smm.so wsrep_cluster_namemydb-cluster wsrep_cluster_addressgcomm://192.168.10.11,192.168.10.12,192.168.10.13 wsrep_node_namedb-node1 wsrep_node_address192.168.10.11 wsrep_sst_methodmariabackup wsrep_sst_authsst_user:strong_password # 性能相关 innodb_buffer_pool_size4G innodb_flush_log_at_trx_commit2 innodb_autoinc_lock_mode2 sync_binlog1逐条解释一下关键参数wsrep_provider指定Galera插件库的位置路径写错会导致启动时直接报错。wsrep_cluster_name集群名称同一个集群的所有节点必须一致。wsrep_cluster_address节点间的连接地址列表。**这里有一个非常关键的区别初始引导第一个节点时这个参数不是这个写法而是要写成gcomm://空地址表示我是一个新集群的起点。**后面会详细说。wsrep_node_name和wsrep_node_address当前节点的标识必须保证集群内唯一。wsrep_sst_method选择SST同步方式我们用的mariabackup。wsrep_sst_authSST同步时使用的数据库账号密码。账号需要提前在所有节点上创建好并授权RELOAD、PROCESS、REPLICATION SLAVE等权限否则节点加入时会同步失败。innodb_autoinc_lock_mode2Galera要求必须设置为2这是它在多主并发写入场景下保证自增ID不冲突的机制。如果写的是默认值1节点启动时就会报错并拒绝启动。关于sync_binlog我个人的实践建议是保持默认值0即可因为Galera不依赖binlog做回放binlog更多是为了后续的数据分析和增量备份服务。如果设置成1会影响写入性能在分布式集群里这个收益和成本不成正比。3.3 第一个节点的初始引导任何一个新集群只能初始化一次这是整个部署过程中最容易出错、也最重要的一步。三个节点全部完成安装和配置之后必须在第一个节点上执行一次特殊启动目的就是告诉Galera“我要创建一个全新的集群”。具体做法是把wsrep_cluster_address临时改成空gcomm地址然后启动MariaDB服务。在MariaDB 10.6的CentOS环境里可以这样操作# 第一个节点先停掉服务 systemctl stop mariadb # 使用galera_new_cluster脚本或手动指定空gcomm启动 galera_new_clustergalera_new_cluster这个脚本做的事情本质上是以gcomm://作为集群地址启动当前节点把这个进程标记为集群中的第一个成员。用这个脚本有个好处——不用临时改配置文件脚本会自动识别并调整启动参数。执行完之后登录数据库验证SHOW STATUS LIKE wsrep_cluster_size;如果返回结果是1说明当前节点已经作为集群的初始成员成功运行。注意这个“初始化集群”的动作在当前节点生命周期内只需要执行一次。如果以后集群中所有节点都停机了需要恢复时要选择数据最新的节点来引导而不是随便挑一个节点执行。这涉及到集群的“脏数据”问题后面会专门讲。3.4 第二、第三个节点的无缝加入第一个节点初始化成功之后其余节点只需要正常启动服务就可以自动加入集群。systemctl start mariadb启动之后节点会根据配置文件里的wsrep_cluster_address去连接其他节点这个过程中会自动触发SST或IST数据同步把第一个节点的数据完整复制过来。数据量较小的情况下可能一两分钟就完成数据量大的情况下需要持续一段时间。可以通过日志观察同步进度tail -f /var/log/mariadb/mariadb.log同步完成之后在任意节点上执行SHOW STATUS LIKE wsrep_cluster_size; SHOW STATUS LIKE wsrep_local_state_comment;如果集群大小显示为3且每个节点的状态都是Synced说明集群已经健康运行。这里有一个实际操作经验值得我们留意第二个节点加入时是最理想的对齐时机。第二个节点加入时往往是通过SST做全量同步的而第三个节点加入时由于前两个节点已经保持一致状态它就有可能使用IST做增量同步速度会快很多。SST是全量同步IST是增量同步它们的自动选择机制比较智能但对于大数据量场景尽量让新节点通过IST加入能省不少时间。3.5 验证集群功能同时写入并发测试集群建立后需要用实际写入来验证多主能力。我建议的做法是在两个不同的节点上分别创建表、写入数据然后验证数据是否实时一致。在节点1执行CREATE DATABASE IF NOT EXISTS test_cluster; USE test_cluster; CREATE TABLE IF NOT EXISTS sync_test (id INT PRIMARY KEY AUTO_INCREMENT, val VARCHAR(100)); INSERT INTO sync_test(val) VALUES (from-node1);在节点2执行USE test_cluster; INSERT INTO sync_test(val) VALUES (from-node2); SELECT * FROM sync_test;此时查询结果里应该同时包含两条记录分别来自不同节点。这验证了Galera的同步复制效果——数据在所有节点上是实时一致的。再回到节点1查询同样能看到节点2写入的数据。这就证明集群的多主特性工作正常。4. 从实际运行中积累的经验集群状态监控、节点恢复与常见故障处理集群部署完成只是第一步日常运维才是考验开始的地方。Galera集群和传统单机或主从环境的运维思路差别很大很多问题如果不了解内幕遇到时会非常抓狂。4.1 理解集群状态字段这些状态值告诉你一切Galera集群没有专门的监控界面所有运行状态都通过数据库状态变量暴露。掌握几个关键状态字段基本就能掌握集群的健康状况。状态变量含义重点关注值wsrep_cluster_size集群当前节点数正常时应与总节点数一致wsrep_cluster_status集群整体状态Primary表示状态良好wsrep_local_state_comment当前节点状态Synced表示数据同步完成wsrep_connected当前节点是否已连接集群ON为正常wsrep_ready当前节点是否可接受查询ON为正常wsrep_flow_control_paused流控暂停比例值越接近0越好长期高于0.5说明集群有压力日常巡检建议重点看这几个字段。我习惯用一条命令快速检查mysql -e SHOW GLOBAL STATUS LIKE wsrep%;重点查看wsrep_cluster_status是否为Primarywsrep_local_state_comment是否为Synced。如果在日志里看到节点状态变成Donor或Joiner那就说明集群正在发生SST同步数据不会丢失但需要关注同步完成后节点是否恢复正常。4.2 节点异常宕机后的恢复流程这是运维中最常见的场景。比如节点2断电了或者服务崩了等你想把它拉起来时正确的处理顺序能帮你省掉很多麻烦。第一步确认该节点数据目录无误然后尝试启动MariaDB服务。systemctl start mariadb第二步如果启动后无法自动加入集群查看日志确认失败原因。常见的错误是gcomm连接超时或者SST认证失败。第三步如果SST认证失败检查wsrep_sst_auth中配置的数据库账号是否正确权限是否还在。账号在节点重启后不会丢失但要检查集群里其他节点是否还存在这个账号。一个实际出现过的情况节点宕机较长时间期间集群发生了大量写入导致宕机节点的binlog和集群其他节点的同步点差距过大。此时该节点无法通过IST增量同步追上进度只能走SST全量同步。SST全量同步期间Donor节点的数据目录会有较大IO压力需要注意观察Donor节点的负载情况。4.3 全集群停机后的重启顺序一台都不能错如果所有节点都停了重启的顺序直接决定了集群能否恢复。很多人在这里栽过跟头——三个节点挨个启动结果集群起不来。原因在于Galera集群需要有一个节点用空gcomm地址引导启动。如果三个节点都用正常配置带地址列表的gcomm地址启动每个节点都会以为自己是去加入一个已存在的集群结果谁都不是初始成员集群就会一直处于不可用状态。正确的做法挑一个数据最新的节点。判断依据是看哪个节点的seqno最大也就是事务序号最新。查看方法是在数据目录下找grastate.dat文件cat /var/lib/mysql/grastate.dat关注其中的seqno字段数值最大者即为数据最新节点。用galera_new_cluster在数据最新节点上引导启动集群。其他节点直接systemctl start mariadb正常启动即可。这里必须强调绝不能为了防止这个麻烦把所有节点的wsrep_cluster_address都改成空gcomm。那样会导致多个节点各自形成独立集群数据直接分叉造成不可逆的一致性事故。4.4 脑裂防护机制为什么宁愿少也不能错Galera通过法定票数机制来消除脑裂。当集群节点之间的网络出现分区时少于半数的节点分区会主动把自己设置为不可用状态拒绝所有读写请求避免产生数据分叉。两节点集群在这方面的缺陷很明显一旦任何一个节点失联剩下的那个节点只有1票无法构成多数派整个集群就会锁死。三节点集群容忍一个节点故障五节点集群容忍两个节点故障。配置文件中可以设置wsrep_auto_increment_controlON另外有几个参数可以帮助集群在异常情况下更快做出决策wsrep_sync_wait控制节点在对外提供服务前是否等待状态同步。默认值0表示不等待可以设置大一些以增强一致性。wsrep_retry_autocommit事务因冲突自动重试的次数适当提高可以减少偶发冲突导致的写入失败。生产环境建议保持wsrep_sync_wait设置为5或7对应节点级别的读操作和元数据操作都等待同步完成代价是单次查询会稍微变慢但能确保业务读取到的是所有节点都确认过的数据。4.5 大事务与全表操作一个容易踩的坑Galera同步复制对事务大小有一项硬性限制默认情况下事务大小超过2GB会直接报错。更关键的限制是一个事务在认证阶段需要被广播到所有节点节点间的网络传输和队列缓冲都有内存开销。超大事务很可能撑爆某个节点的内存缓冲区。实际运维中见过一个案例——某个系统在统计类需求里一次性UPDATE了数百万行记录结果直接把集群拖到流控状态所有节点的写入都被暂停持续了几分钟才恢复。解决思路是让业务方把大事务拆成小批量提交每次处理几千行就COMMIT这样对集群的冲击就会小很多。对于超大表的结构变更DDL操作情况类似。建议在低峰期执行并有心理预期集群中的DDL会阻塞所有节点的写入操作时间越长阻塞越久。如果数据量确实很大可以考虑组件在某个节点上执行DDL然后观察集群状态确认同步完成后再在业务上进行切换。4.6 密码认证与SST账号管理最容易被忽略的细节集群部署完成后SST的认证账号往往就躺在配置文件里没人管了。这个账号拥有RELOAD、PROCESS、REPLICATION SLAVE权限是运维安全链条里不可忽视的一环。建议做好两件事一是使用独立账号权限最小化不要直接使用root。二是在配置文件中用单独的文件保存认证信息设置权限为600避免被无关人员读取。chmod 600 /etc/my.cnf.d/galera.cnf另外Galera集群节点之间流转的数据是明文格式节点间通信没有额外的加密层。如果网络环境是跨机房或者不可控的网络要慎重评估数据暴露风险。MariaDB 10.6并不原生提供Galera节点间的TLS加密方案开箱即用需要额外配置这一点在方案选型时就要想清楚。5. 实用工具与调优进阶让集群跑得更稳更高效简单地把集群跑起来不算难真正考验功力的是如何调优如何让它在你的业务负载下发挥出最好的性能。5.1 流控机制理解Galera的自我保护和性能开关流控Flow Control是Galera集群自动保护机制的核心。当某个节点的执行队列超过阈值时集群会启动流控暂停所有写入操作等待慢节点追上来。通过以下命令监控流控情况SHOW STATUS LIKE wsrep_flow_control_paused; SHOW STATUS LIKE wsrep_flow_control_sent; SHOW STATUS LIKE wsrep_flow_control_recv;wsrep_flow_control_paused表示集群因流控暂停的时间比例。如果长期高于0.3甚至0.5说明集群中某个节点处理能力明显落后或者网络延迟过大。此时要做的是找出慢节点检查它的磁盘IO、CPU负载、网络延迟。确认慢节点相关的业务查询是否占用过多资源。比如某个节点上有大量报表查询频繁全表扫描抢占了IO就会拖累集群整体的写入能力。适当增加gcs.fc_limit参数让触发流控的阈值更高一些。配置文件里加[galera] gcs.fc_limit 100 gcs.fc_factor 0.8其中的fc_limit可以理解为允许的发送队列大小上限fc_factor是指达到多大比例时开始触发流控。这些参数的效果需要结合业务实际情况观察没有通用的最优值。5.2 gcache大小决定节点能否走快速增量同步路径gcache是Galera在每个节点上维护的一个环形缓存文件。它的作用很直接当某个节点短暂离线后又重新加入集群时如果集群当前的同步点还在其他节点的gcache范围内就可以用IST做增量同步速度快、不阻塞业务如果集群的commit进度已经超出gcache大小则只能通过SST做全量同步耗时和资源消耗都大得多。默认的gcache.size是128MB对很多业务来说偏小了。建议根据实际写入量来估算如果一天产生10GB的binlog那么gcache至少配置1GB以上才能让节点在短暂掉线后有较大概率走IST。配置文件里这样设置[galera] gcache.size 2G gcache.page_size 128Mgcache.size的物理文件在数据目录下扩展它不会回收已有空间所以从128M改到2G后磁盘占用会增长。磁盘规划时要注意预留空间。另外gcache文件所在的磁盘I/O性能会影响节点恢复速度建议用独立的磁盘或高性能磁盘来存放。5.3 慢查询分析和参数优化思路Galera集群的慢查询很大一部分原因不在数据库本身而在网络和同步机制。一个事务在节点A提交后需要把写集广播到节点B、C等待它们认证并反馈才会真正返回客户端。网络延迟RTT对写入性能的影响几乎是线性的。有几个典型参数值得关注innodb_flush_log_at_trx_commit默认值1每次提交都刷磁盘安全但慢。在Galera环境下由于节点间已经有同步确认机制可以设置为2减少磁盘刷新的频率提升吞吐而整体安全性仍然由集群的同步复制保证。我们生产环境也是设置成2运行正常。innodb_buffer_pool_size根据物理内存设置一般建议设为物理内存的50%-70%。这个参数对读性能影响极大。innodb_log_file_sizeInnoDB重做日志大小在MariaDB 10.6中默认是100M左右。写入密集场景建议调大到512M甚至1G减少日志文件切换带来的磁盘IO抖动。wsrep_provider_options可以针对网络协议参数微调。比如增加socket缓冲区大小wsrep_provider_optionssocket.ssl0; gcache.size2G; gcs.recv_buf1048576; gcs.recv_q_size40965.4 备份策略Galera集群不能简单依赖单节点备份很多人觉得集群里数据每个节点都有一份不需要再备份了。这个想法有其合理性但也要看到风险所在如果所有节点都在同一台物理机或同一机房一个机房级的故障就能把所有副本一起带走。而且如果发生误操作比如错误地删除了某张表同步复制机制会把这个删除操作广播到所有节点——所有节点会一起把表删掉。这才是完整的风险分析。所以备份策略依然是必要的。推荐两种方式一种是在业务低峰期对某个节点做mariabackup物理备份mariabackup --backup --target-dir/backup/mysql_$(date %F) --userbackup_user --passwordxxx另一种是启用binlog并定期做增量备份。Galera集群的binlog仍然是每节点独立记录分析或回放时要注意集群整体的事务一致性比较复杂。但如果只是为了保留历史数据、应对误删操作这个方案配合全量备份就已经能覆盖大部分恢复场景了。5.5 客户端连接配置读写分离如何做才合理Galera是多主架构理论上所有节点都支持读写应用层无需做读写分离。但在实际负载较大时让所有写流量都分散到三个节点反而增加了写冲突的概率两个节点同时更新同一行就会产生认证冲突。因此更稳妥的做法是写流量集中到一个节点比如默认就走节点1。读流量分散到三个节点均衡负载。某个节点故障时写流量自动切换到其他节点应用程序的连接池会自动完成这个转移。可以使用简单的HAProxy配置来做到读写分流的自动切换这里不详细展开。需要注意的是应用层要做好连接失败后的重试机制。Galera节点踢出或加入时有短暂的服务中断窗口应用如果一次性请求就直接报错体验会很差。6. 常见踩坑记录我这边的排查链路与最终解法最后把实际运维中遇到的几个棘手情况记录一下希望读者遇到类似问题能少走弯路。6.1 节点启动后一直卡在Joining状态无法变为Synced现象新节点加入集群后状态一直停在Joining数据库能连接但无法写入。排查链路第一步查看MariaDB错误日志tail -n 100 /var/log/mariadb/mariadb.log看到的关键报错差不多是SST失败相关的。有次是权限不足日志提示访问被拒绝通过修正SST账号权限解决。第二步如果日志里没有明显错误检查SST端口4444是否放通。SST过程是由Donor节点的mariabackup备份数据然后通过4444端口传送到Joiner的。网络不通时日志会超时但是界面上的提示异常码有时并不直观。第三步确认磁盘空间。Joiner节点接收全量数据时需要和源数据差不多大小的磁盘空间如果空间不足mariabackup会直接失败。当时那个环境正好赶上磁盘告警清理完日志文件和过期备份后重新触发SST就正常了。还有一个细节SST同步期间不能重启数据库服务否则同步进程会被中断出现节点状态反复横跳的情况。处理方式是等同步完成或者先关停服务删掉数据目录中的数据再重新启动触发一次干净的SST。6.2 集群Primary状态丢失后的恢复方法现象因为网络抖动或误操作某个节点报错集群状态从Primary变成了非Primary比如出现unknown此时所有节点都拒绝写入。处理方式找到拥有最新数据的节点用safe_to_bootstrap为1的节点引导集群。查看grastate.datcat /var/lib/mysql/grastate.dat如果文件中的safe_to_bootstrap1这个节点就是被标记为可安全引导的节点。如果所有节点都是safe_to_bootstrap0需要人工判断最新数据的节点。判断依据是看seqno最大的那个是数据最全的。用如下命令强制引导集群mysqld --wsrep-cluster-addressgcomm:// --wsrep-new-cluster或者停掉服务后用脚本galera_new_cluster其他节点再依次启动。等待集群恢复Primary状态后立即做一次全量备份避免后续再出问题。必须避免的一个操作在Primary状态丢失后直接对多个节点同时执行空gcomm引导启动。这会造成多个独立集群分叉数据彻底不一致比宕机还难恢复。6.3 写冲突导致的死锁错误与业务并发控制多主架构下两个节点同时对同一行数据做更新就可能触发死锁MySQL返回的错误码是1213。这是Galera与单机MySQL在行为上的一个显著差异。缓解手段包括应用层做数据分片让同一行数据的修改尽量固定落在同一个节点上。比如按用户ID取模路由。开启事务时使用SELECT ... FOR UPDATE先抢锁降低并发冲突概率。提高wsrep_retry_autocommit参数值让MySQL自动重试一些因冲突失败的autocommit事务SET GLOBAL wsrep_retry_autocommit 10;但要注意显式开启事务的多语句操作不会自动重试只能靠应用层处理重试逻辑。6.4 版本升级的注意事项尽量使用滚动升级方式MariaDB 10.6本身是稳定版本但后续的补丁版本升级也需要注意。Galera集群的滚动升级思路是逐节点升级先升级一个节点确认它加入集群正常后再升级下一个。滚动升级步骤选一个节点停服务。安装新版本包。启动服务观察该节点重新加入集群的状态。确认状态为Synced后等待集群内其他节点数据对齐再升级下一个节点。不建议直接停掉所有节点一次性升级尤其在有业务在跑的环境里风险大而且回退困难。升级前一定做全量备份并且保留旧版本的安装包以便回退。6.5 关于数据一致性验证的长期建议Galera集群虽然保证同步复制但定期做数据一致性校验仍然是好习惯。推荐使用pt-table-checksum这类工具做周期性的数据对比。需要注意这类工具会产生较大的查询负载最好是业务低峰期执行逐个节点轮着做避免同一时间所有节点都在跑校验。我自己的习惯是每周做一次数据一致性抽查每个月做一次全量校验。从实际效果来看Galera集群的数据一致性可靠程度是比较高的至今还没发现过不一致的情况。但这件事让人觉得安心说明机制本身确实在正常发挥作用。7. 写在最后的实践经验MariaDB 10.6 Galera Cluster整套部署下来我的体会是技术方案本身并不复杂但细节决定了这套集群能不能长期稳定运行。某种程度上Galera的运维思路和传统主从很不一样。传统主从出了故障主库从库的关系需要人工理顺Galera则倾向于自动愈合——节点错乱、网络抖动后只要数据没有分叉它能自己恢复。这种“自我修复”的能力极大减轻了日常运维负担也是在项目中选择它的一个重要理由。如果是从零开始搭建我的建议是这样的路线先做虚拟机实验环境把3节点集群搭起来跑通把节点宕机、全集群重启、SST/IST切换这些场景都演练一遍再放上生产业务。实验环境里踩坑的成本低等熟练了再上线生产环境的稳定性就有保障得多。这套组合拳打下来数据库这块就踏实了。