MySQL MGR环境MDL锁堵塞案例分析

来源:这里教程网 时间:2026-03-01 18:34:38 作者:

1 、故障描述

某次某用户的 MySQL 集群 mgr 主节点产生大量 running 连接且长时间无法执行完成,详细信息如下所示:    

 

2 、根因分析

根据提示,初步判断是有大量事务未提交,导致锁无法释放。但这两个截图无法确定是哪个事务占用了锁导致,需要进一步排查。

尝试先将问题线程 kill 掉,再做跟踪观察,如下:

    select * from information_schema.processlist where command !='Sleep';  

确实可以发现,此时出现了很多的 MDL 锁等待情况,正常情况下,执行 create database 不会有 MDL 锁存在,从语句上来看,是去判断库是否存在,不存在就创建。而这些库其实是存在的,业务上一直在做判断执行。

那么很有可能是当前库下有 DML 操作,执行该 DDL 操作,会等待所有 DML 操作完成才能执行,而 DDL 之后又执行的 DML 又需要等待该 DDL 完成,从而导致了恶心循环,一般这种情况再 rr 隔离级别容易出现。此时去查看当前实例的隔离级别,发现确实是 RR ,如下:

mysql> show variables like 'transaction_isolation';

+-----------------------+----------------+

| Variable_name         | Value          |

+-----------------------+----------------+

| transaction_isolation | READ- REPEATABLE |

+-----------------------+----------------+

1 row in set (0.00 sec)

当然,排查过程中还发现了 BUFFER 缓冲内存配置较低,在高频查询场景中可能会出现严重的性能问题,如下:

show variables like 'innodb_buffer_pool_size' ;

+-------------------------+-----------+

| Variable_name           | Value     |

+-------------------------+-----------+

| innodb_buffer_pool_size | 134217728 |

+-------------------------+-----------+

内存设置太小, MySQL 根本无法进行缓存以及上下文切换。可根据实际情况将内存扩大至服务器内存的 60%

 

3 、解决方案

1 、在线将 MySQL 事务隔离级别改为 RC

set global transaction isolation level read committed;

添加到配置文件 my.cnf

transaction-isolation=READ-COMMITTED

Kill 掉全部有锁的 SQL 或者重启实例 , 观察新 session ,恢复正常

 

2 、将 buffer 手动扩容至 10GB

set global innodb_buffer_pool_size   = 10*1024*2014*1024

 

相关推荐