如何排查MDL锁

简介: 分享数据库故障处理的微信公众号:MySQL_DBA,欢迎关注,谢谢!

之前遇到一个DBA,在生产库上加字段,导致数据库连接数打满。原因就是MDL锁引起。下面让我来介绍一下MDL锁及其排查和处理方式。


MDL锁:

全称meta data lock,是表锁,用于保护数据库对象定义不被修改。执行SQL语句操作表都是需要获取和持有MDL锁,直到锁被释放。


案例描述:

一位同学查询只有2条数据的test.tt1,10秒后却返回锁等待超时报错


案例警示:

  1. 要对生产数据库有敬畏之心
  2. 业务高峰,不建议对大表和热表做DDL变更(推荐gh-ost)
  3. 有效的数据库备份,重于一切
  4. 良好的数据库运维规范是减少故障的基础(DBA风险操作,需要审核和通知业务方)


技术回放:

数据库版本、表结构和报错信息,如下

mysql>select version();+---------------+| version()|+---------------+|5.7.38-41-log |+---------------+1 row inset(0.54 sec)mysql> show createtable  tmp_mdl_lock ;+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|Table|CreateTable|+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| tmp_mdl_lock |CREATETABLE `tmp_mdl_lock` (  `id` int(11)NOTNULL AUTO_INCREMENT,  `name` varchar(10) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 |+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row inset(0.00 sec)mysql>select*from test.tmp_mdl_lock;ERROR 1205(HY000): Lock wait timeout exceeded; try restarting transaction

拓展:

lock_wait_timeout设置了10秒,因此上面的SQL执行了10秒报锁等待超时错误

如果表 test.tmp_mdl_lock上的查询语句频繁,而且客户端有重试机制,也就是说超时后会再起一个新SESSION再请求的话,这个库的线程很快就会爆满


DBA分析和处理过程:

1.首先查看会话信息,发现Waiting for table metadata lock,确认为DML锁引起

select*from information_schema.processlistwhere info isnotnull;+-----------+------+-----------+------+---------+------+---------------------------------+---------------------------------------------------------------------+---------+-----------+---------------+| ID        | USER | HOST      | DB   | COMMAND |TIME| STATE                           | INFO                                                                | TIME_MS | ROWS_SENT | ROWS_EXAMINED |+-----------+------+-----------+------+---------+------+---------------------------------+---------------------------------------------------------------------+---------+-----------+---------------+|251182208| root | localhost |NULL| Query   |0| executing                       |select*from information_schema.processlistwhere info isnotnull|2|0|0||251181173| root | localhost |NULL| Query   |3| Waiting for table metadata lock |select*from test.tmp_mdl_lock|3077|0|0|+-----------+------+-----------+------+---------+------+---------------------------------+---------------------------------------------------------------------+---------+-----------+---------------+

2.查询持有并导致其他事务阻塞的连接会话

select*from   sys.schema_table_lock_waits   \G
***************************1. row ***************************               object_schema: test
                 object_name: tmp_mdl_lock
           waiting_thread_id:251885079                 waiting_pid:251181173             waiting_account: root@localhost
           waiting_lock_type: SHARED_READ
       waiting_lock_duration: TRANSACTION
               waiting_query:select*from test.tmp_mdl_lock          waiting_query_secs:10 waiting_query_rows_affected:0 waiting_query_rows_examined:0          blocking_thread_id:251884951                blocking_pid:251181044            blocking_account: root@localhost
          blocking_lock_type: SHARED_NO_READ_WRITE
      blocking_lock_duration: TRANSACTION
     sql_kill_blocking_query: KILL QUERY 251181044sql_kill_blocking_connection: KILL 2511810441 row inset(0.05 sec)拓展:sys.schema_table_lock_waits默认为空,请打开mdl对应的instrument;
show global variables like'performance_schema';+--------------------+-------+| Variable_name      | Value |+--------------------+-------+| performance_schema |ON|+--------------------+-------+update  setup_instruments set ENABLED ='yes',timed ='yes'where  NAME ='wait/lock/metadata/sql/mdl';select*from setup_instruments   where name ='wait/lock/metadata/sql/mdl';+----------------------------+---------+-------+| NAME                       | ENABLED | TIMED |+----------------------------+---------+-------+| wait/lock/metadata/sql/mdl | YES     | YES   |

3.KILL 251181044,断开线程的连接;

拓展:

kill query 线程id,表示终止这个线程中正在执行的语句;kill 线程id,表示断开这个线程的连接,这个连接中未提交的事务会回滚、在执行的SQL会停止

目录
相关文章
|
JavaScript 前端开发 安全
JavaScript中的循环控制:while、do-while与for详解
【4月更文挑战第7天】本文探讨JavaScript的三种主要循环结构:while、do-while和for。while循环在满足条件时执行代码块,注意避免无限循环;do-while循环至少执行一次,适合先执行后判断的场景;for循环结合初始化、条件和迭代,适合遍历。理解每种循环的特点和适用场景,结合编程技巧,如使用break和continue,选择合适的循环方式,能提升代码效率和可读性。记得关注循环性能和避免不必要的计算。
506 0
|
12月前
|
人工智能 关系型数据库 MySQL
AnalyticDB MySQL版:云原生离在线一体化数据仓库支持实时业务决策
AnalyticDB MySQL版是阿里云推出的云原生离在线一体化数据仓库,支持实时业务决策。产品定位为兼具数据库应用性和大数据处理能力的数仓,适用于大规模数据分析场景。核心技术包括混合负载、异构加速、智能弹性与硬件优化及AI集成,支持流批一体架构和物化视图等功能,帮助用户实现高效、低成本的数据处理与分析。通过存算分离和智能调度,AnalyticDB MySQL可在复杂查询和突发流量下提供卓越性能,并结合AI技术提升数据价值挖掘能力。
361 16
|
缓存 应用服务中间件 Linux
yum 命令下载软件包到本地
在 Linux 系统中,使用 yum 命令可以下载软件包但不安装。通过 yum 的下载缓存功能,可以快速获取软件包。常用命令包括:`yum list available` 列出可安装的软件包,`yum download nginx` 下载特定软件包,`yum download nginx-1.18.0` 下载特定版本,`yum download -resolve nginx` 下载软件包及其依赖,`yum download nginx -d /path/to/download/directory` 指定下载目录
989 1
|
监控 数据可视化 Java
如何使用JDK自带的监控工具JConsole来监控线程池的内存使用情况?
如何使用JDK自带的监控工具JConsole来监控线程池的内存使用情况?
|
存储 NoSQL Java
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
该博客文章展示了如何在Linux虚拟机上使用Redis和Jedis客户端实现手机验证码的验证功能,包括验证码的生成、存储、验证以及限制每天发送次数的逻辑,并提供了测试结果截图。
使用redis进行手机验证码的验证、每天只能发送三次验证码 (redis安装在虚拟机linux系统中)
|
SQL 关系型数据库 MySQL
在 MySQL 中使用 Concat
【8月更文挑战第11天】
689 0
在 MySQL 中使用 Concat
|
网络协议 Linux Windows
ping命令详解
ping命令详解
562 1
|
消息中间件 运维 Apache
消息队列 MQ产品使用合集之消费者在消费完成后没有关闭链接,导致连接数达到上限,该如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
存储 传感器 时序数据库
时序数据库influx有字符串拼接函数吗
【6月更文挑战第25天】时序数据库influx有字符串拼接函数吗
273 0