news 2026/10/21 6:05:35

MariaDB Galera Cluster部署实战:多主同步复制与高可用架构

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MariaDB Galera Cluster部署实战:多主同步复制与高可用架构

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和TCP
4568IST(Incremental State Transfer,增量状态传输)端口
4444SST(State Snapshot Transfer,全量状态快照传输)端口,使用mariabackup时常用

放通防火墙的命令大致如下(以firewalld为例):

firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --permanent --add-port=4567/tcp firewall-cmd --permanent --add-port=4567/udp firewall-cmd --permanent --add-port=4568/tcp firewall-cmd --permanent --add-port=4444/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_method=mariabackup

使用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 = ROW

binlog_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-version=10.6

然后安装:

dnf install -y MariaDB-server MariaDB-client mariadb-backup

Galera的实现是作为一个插件动态加载到MariaDB中的,不再需要额外安装独立的galera包,这也是10.6版本之后的便利之处。安装完成后可以检查一下相关文件是否存在:

ls /usr/lib64/galera/

能看到类似libgalera_smm.so的文件就说明插件库已经就位。

3.2 配置文件的核心参数逐一说明

MariaDB的配置文件默认路径是/etc/my.cnf.d/,建议单独创建一个galera.cnf文件来存放集群相关配置,避免和默认配置混在一起。

[mysqld] # 基础设置 server-id=1 log-bin=mysql-bin binlog_format=ROW transaction-isolation=READ-COMMITTED default-storage-engine=InnoDB # Galera相关配置 wsrep_on=ON wsrep_provider=/usr/lib64/galera/libgalera_smm.so wsrep_cluster_name="mydb-cluster" wsrep_cluster_address="gcomm://192.168.10.11,192.168.10.12,192.168.10.13" wsrep_node_name="db-node1" wsrep_node_address="192.168.10.11" wsrep_sst_method=mariabackup wsrep_sst_auth="sst_user:strong_password" # 性能相关 innodb_buffer_pool_size=4G innodb_flush_log_at_trx_commit=2 innodb_autoinc_lock_mode=2 sync_binlog=1

逐条解释一下关键参数:

  • wsrep_provider:指定Galera插件库的位置,路径写错会导致启动时直接报错。
  • wsrep_cluster_name:集群名称,同一个集群的所有节点必须一致。
  • wsrep_cluster_address:节点间的连接地址列表。**这里有一个非常关键的区别:初始引导第一个节点时,这个参数不是这个写法,而是要写成gcomm://空地址,表示我是一个新集群的起点。**后面会详细说。
  • wsrep_node_name和wsrep_node_address:当前节点的标识,必须保证集群内唯一。
  • wsrep_sst_method:选择SST同步方式,我们用的mariabackup。
  • wsrep_sst_auth:SST同步时使用的数据库账号密码。账号需要提前在所有节点上创建好,并授权RELOAD、PROCESS、REPLICATION SLAVE等权限,否则节点加入时会同步失败。
  • innodb_autoinc_lock_mode=2:Galera要求必须设置为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_cluster

galera_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是否为Primary,wsrep_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地址)启动,每个节点都会以为自己是去加入一个已存在的集群,结果谁都不是初始成员,集群就会一直处于不可用状态。

正确的做法:

  1. 挑一个数据最新的节点。判断依据是看哪个节点的seqno最大,也就是事务序号最新。查看方法是在数据目录下找grastate.dat文件:
cat /var/lib/mysql/grastate.dat

关注其中的seqno字段,数值最大者即为数据最新节点。

  1. 用galera_new_cluster在数据最新节点上引导启动集群。

  2. 其他节点直接systemctl start mariadb正常启动即可。

这里必须强调:绝不能为了防止这个麻烦,把所有节点的wsrep_cluster_address都改成空gcomm。那样会导致多个节点各自形成独立集群,数据直接分叉,造成不可逆的一致性事故。

4.4 脑裂防护机制:为什么宁愿少也不能错

Galera通过法定票数机制来消除脑裂。当集群节点之间的网络出现分区时,少于半数的节点分区会主动把自己设置为不可用状态,拒绝所有读写请求,避免产生数据分叉。

两节点集群在这方面的缺陷很明显:一旦任何一个节点失联,剩下的那个节点只有1票,无法构成多数派,整个集群就会锁死。三节点集群容忍一个节点故障,五节点集群容忍两个节点故障。

配置文件中可以设置:

wsrep_auto_increment_control=ON

另外有几个参数可以帮助集群在异常情况下更快做出决策:

  • 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,说明集群中某个节点处理能力明显落后,或者网络延迟过大。此时要做的是:

  1. 找出慢节点,检查它的磁盘IO、CPU负载、网络延迟。
  2. 确认慢节点相关的业务查询是否占用过多资源。比如某个节点上有大量报表查询,频繁全表扫描抢占了IO,就会拖累集群整体的写入能力。
  3. 适当增加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 = 128M

gcache.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_size:InnoDB重做日志大小,在MariaDB 10.6中默认是100M左右。写入密集场景建议调大到512M甚至1G,减少日志文件切换带来的磁盘IO抖动。
  • wsrep_provider_options:可以针对网络协议参数微调。比如增加socket缓冲区大小:
wsrep_provider_options="socket.ssl=0; gcache.size=2G; gcs.recv_buf=1048576; gcs.recv_q_size=4096"

5.4 备份策略:Galera集群不能简单依赖单节点备份

很多人觉得集群里数据每个节点都有一份,不需要再备份了。这个想法有其合理性,但也要看到风险所在:如果所有节点都在同一台物理机或同一机房,一个机房级的故障就能把所有副本一起带走。而且如果发生误操作,比如错误地删除了某张表,同步复制机制会把这个删除操作广播到所有节点——所有节点会一起把表删掉。这才是完整的风险分析。

所以备份策略依然是必要的。推荐两种方式:

一种是在业务低峰期对某个节点做mariabackup物理备份:

mariabackup --backup --target-dir=/backup/mysql_$(date +%F) --user=backup_user --password=xxx

另一种是启用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.dat:

cat /var/lib/mysql/grastate.dat

如果文件中的safe_to_bootstrap=1,这个节点就是被标记为可安全引导的节点。如果所有节点都是safe_to_bootstrap=0,需要人工判断最新数据的节点。判断依据是看seqno,最大的那个是数据最全的。

用如下命令强制引导集群:

mysqld --wsrep-cluster-address=gcomm:// --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集群的滚动升级思路是:逐节点升级,先升级一个节点,确认它加入集群正常后,再升级下一个。

滚动升级步骤:

  1. 选一个节点,停服务。
  2. 安装新版本包。
  3. 启动服务,观察该节点重新加入集群的状态。
  4. 确认状态为Synced后,等待集群内其他节点数据对齐,再升级下一个节点。

不建议直接停掉所有节点一次性升级,尤其在有业务在跑的环境里,风险大而且回退困难。升级前一定做全量备份,并且保留旧版本的安装包,以便回退。

6.5 关于数据一致性验证的长期建议

Galera集群虽然保证同步复制,但定期做数据一致性校验仍然是好习惯。推荐使用pt-table-checksum这类工具做周期性的数据对比。需要注意:这类工具会产生较大的查询负载,最好是业务低峰期执行,逐个节点轮着做,避免同一时间所有节点都在跑校验。

我自己的习惯是每周做一次数据一致性抽查,每个月做一次全量校验。从实际效果来看,Galera集群的数据一致性可靠程度是比较高的,至今还没发现过不一致的情况。但这件事让人觉得安心,说明机制本身确实在正常发挥作用。

7. 写在最后的实践经验

MariaDB 10.6 Galera Cluster整套部署下来,我的体会是:技术方案本身并不复杂,但细节决定了这套集群能不能长期稳定运行。

某种程度上,Galera的运维思路和传统主从很不一样。传统主从出了故障,主库从库的关系需要人工理顺;Galera则倾向于自动愈合——节点错乱、网络抖动后,只要数据没有分叉,它能自己恢复。这种“自我修复”的能力,极大减轻了日常运维负担,也是在项目中选择它的一个重要理由。

如果是从零开始搭建,我的建议是这样的路线:先做虚拟机实验环境,把3节点集群搭起来跑通,把节点宕机、全集群重启、SST/IST切换这些场景都演练一遍,再放上生产业务。实验环境里踩坑的成本低,等熟练了再上线,生产环境的稳定性就有保障得多。这套组合拳打下来,数据库这块就踏实了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 6:05:33

投票数据深度洞察:从增量曲线到黑马预测的实战方法

1. 投票数据全貌与总排名走势解析1.1 2026年1月21日9时核心榜单快照昨晚我盯数据盯到凌晨一点&#xff0c;今天早上九点又准时截了一轮后台快照。博客之星投票活动已经进入后半程&#xff0c;每天的票数曲线、排名变动、增量分布&#xff0c;都会直接影响最终获奖格局。先说结论…

作者头像 李华
网站建设 2026/10/21 6:05:20

Docker Desktop进阶指南:从资源管理到排障实战

上篇把 Docker Desktop 装好、跑通第一个容器&#xff0c;很多人就觉得"工具已经会了"。但说实话&#xff0c;从"装好的玩具"到"日常吃饭的家伙"&#xff0c;中间还隔着一整条路。资源怎么分才不卡、镜像怎么管才不乱、容器一旦崩了数据还在不在…

作者头像 李华
网站建设 2026/10/21 6:04:06

BitVLA: 1-bit Vision-Language-Action Models for Robotics Manipulation

本文关注于通过模型设计和优化提高VLA架构的效率&#xff0c;而不是依赖推断后压缩的策略。具体地&#xff0c;设计了一种对于机器人操作的全1比特VLA模型&#xff0c;其中每个参数是三值的{-1&#xff0c;0&#xff0c;1}。BitVLA建立在公开的1比特LLM模型BitNeTb1.58&#xf…

作者头像 李华
网站建设 2026/10/21 6:03:15

Linux进程通信之管道详解:匿名管道与FIFO实战

Linux下跑多进程程序&#xff0c;第一道坎就是进程通信。我在一个并发任务分发模块里遇到过这样的事&#xff1a;主进程fork出几个工人进程后&#xff0c;父进程里改了变量&#xff0c;子进程完全看不到&#xff0c;反过来也一样。原因其实不复杂——每个进程都有独立的地址空间…

作者头像 李华
网站建设 2026/10/21 6:03:12

定积分在机器学习中的核心作用:从连续求和的原理到工程实践

最近在后台看到一条挺有意思的提问&#xff1a;上一篇文章讲完导数和梯度下降&#xff0c;我知道优化就是在调斜率&#xff0c;但定积分在机器学习里到底有什么用&#xff1f;总不能天天去算曲线下的面积吧。这个问题问到了关键处。定积分表面上是个几何概念&#xff0c;但它在…

作者头像 李华
网站建设 2026/10/21 6:01:16

Python旅游数据分析可视化系统:从数据采集到动态图表全解析

如果你正在为毕业设计选题发愁&#xff0c;并且对Python有一定基础&#xff0c;那我强烈推荐“基于Python的旅游数据分析可视化系统”这个方向。这个题目看起来普通&#xff0c;但它恰好踩中了毕设评审的几个关键得分点&#xff1a;有完整的数据处理链路、有可视化的直观展示、…

作者头像 李华