MariaDB 10.5.13 Galera集群高负载下Signal 11崩溃原因排查
环境配置
- 数据库:MariaDB 10.5.13 + Galera Cluster,采用InnoDB存储引擎
- 实例:AWS t3.medium
- 内存使用详情见附图
- My.cnf配置如下:
# 原配置内容保留...
问题描述
数据库偶发Signal 11错误崩溃。已知Galera Cluster不支持GET_LOCK/RELEASE_LOCK,但相关代码为前期遗留。疑问:这些查询是否可能引发内存问题导致崩溃?查询通常运行正常,但每数月会崩溃一次,不确定是查询本身还是内存过载导致。
崩溃场景
场景1
- 00:08-00:09一分钟内约1000笔事务,每笔均使用GET_LOCK/RELEASE_LOCK加锁并修改行数据
- 数据库触发Signal 11错误(见附图)
- 约25分钟后,数据库因Signal 6错误崩溃(见附图)
场景2
- 同场景1的高事务负载情况
- 数据库发生段错误,触发Signal 11并崩溃(见附图)
- 日志显示问题与RELEASE_LOCK查询相关
查询流程(敏感信息脱敏,逻辑一致)
该流程循环获取门店并计算当日订单金额,涉及表:company(门店)、bucket、bucket_item、product、tx(门店交易)
[1] 查询所有company,返回1000条结果 [2] 循环处理每个company: [3] 开启根事务 [4] SELECT ... FROM bucket ... FOR UPDATE(加锁读取) [5] 开启嵌套事务 [6] WITH ... SELECT ... FROM bucket_item ... FOR UPDATE(加锁读取) [7] UPDATE bucket ...(更新总价) [8] SELECT GET_LOCK(CONCAT("AA_", #{key}), #{timeoutSeconds})(获取锁) [9] INSERT INTO tx ...(注册交易) [10] SELECT RELEASE_LOCK(CONCAT("AA_", #{key}))(释放锁) [11] INSERT INTO bucket_tx ...(关联订单与交易) [12] 依次关闭嵌套事务与根事务
排查结论与分析
核心诱因:GET_LOCK/RELEASE_LOCK与Galera的兼容性问题
- Galera对会话锁的本质限制:Galera基于事务复制,而GET_LOCK/RELEASE_LOCK是会话级元数据锁,不属于InnoDB事务锁范畴,Galera无法跨节点同步这类锁的状态。高并发场景下大量调用这两个函数,会触发节点内部锁管理逻辑冲突,导致内存访问异常(Signal 11本质是段错误,即进程访问了非法内存地址)。
- 日志指向性验证:场景2明确显示崩溃与RELEASE_LOCK直接相关,说明高负载下释放锁的操作触发了MariaDB 10.5.13的已知bug——Galera环境中,会话锁的释放可能因状态未被正确同步或清理,导致内存指针越界,最终引发崩溃。
- 偶发特性的解释:低负载下锁的创建/释放频率低,冲突概率小;高负载(如1分钟1000笔事务)时,锁的快速流转会放大逻辑漏洞,触发内存异常,这与“数月崩溃一次”的现象完全匹配(仅在高并发时段触发)。
内存限制的次要影响
AWS t3.medium默认内存为4GB,若my.cnf内存配置(如innodb_buffer_pool_size、query_cache_size)不合理,高负载下可能加剧内存紧张,但Signal 11是内存访问非法而非内存耗尽(内存耗尽通常触发OOM kill或Signal 9),因此内存限制是诱因而非直接原因。
修复建议
- 立即替换GET_LOCK/RELEASE_LOCK:改用InnoDB行级锁/表级锁,或基于业务逻辑实现分布式锁(如Redis),避免使用Galera不支持的会话锁。
- 升级MariaDB版本:MariaDB 10.5后续版本(如10.5.20+)修复了部分Galera环境下锁管理的内存漏洞,可降低崩溃概率。
- 优化事务流程:避免循环中开启大量事务,合并批量操作;减少嵌套事务使用,降低锁竞争与内存占用。
内容的提问来源于stack exchange,提问作者samsamsamsmasma
相关产品推荐
相关产品推荐

