MDL全称为metadata lock,即元数据锁。MDL锁主要作用是维护表元数据的数据一致性,在表上有活动事务(显式或隐式)的时候,不可以对元数据进行写入操作。因此从MySQL5.5版本开始引入了MDL锁,来保护表的元数据信息,用于解决或者保证DDL操作与DML操作之间的一致性。

模拟和定位MDL锁

表结构

CREATE TABLE `t` (

`id` int(11) NOT NULL,

`c` int(11) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

会话模拟

session A

session B

lock table t write

select * from t where id =1

session A 通过 lock table 命令持有表 t 的 MDL 写锁,而 session B 的查询需要获取 MDL 读锁。所以,session B 进入等待状态。

mysql> select * from processlist;

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

| ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |

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

| 3582 | tenmao | localhost | tenmao | Sleep | 115 | | NULL |

| 3583 | tenmao | localhost | tenmao | Query | 97 | Waiting for table metadata lock | select * from t where t=1 |

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

冲突解决

这类问题的处理方式,就是找到谁持有 MDL 写锁,然后把它 kill 掉。但是,由于在 show processlist 的结果里面,session A 的 Command 列是“Sleep”,导致查找起来很不方便。不过有了 performance_schema 和 sys 系统库以后,就方便多了。(MySQL 启动时需要设置 performance_schema=on,相比于设置为 off 会有 10% 左右的性能损失)通过查询 sys.schema_table_lock_waits 这张表,我们就可以直接找出造成阻塞的 process id,把这个连接用 kill 命令断开即可。

mysql> SELECT blocking_pid FROM sys.schema_table_lock_waits;

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

| blocking_pid |

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

| 3582 |

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

如何优化与避免MDL锁

MDL锁一旦发生会对业务造成极大影响,因为后续所有对该表的访问都会被阻塞,造成连接积压。我们日常要尽量避免MDL锁的发生,下面给出几点优化建议可供参考:

开启metadata_locks表记录MDL锁。

设置参数lockwaittimeout为较小值,使被阻塞端主动停止。

规范使用事务,及时提交事务,避免使用大事务。

增强监控告警,及时发现MDL锁。

DDL操作及备份操作放在业务低峰期执行。

少用工具开启事务进行查询,图形化工具要及时关闭。

参考

mysql mdl 锁_MySQL MDL锁相关推荐

  1. mysql全局读写怎么锁_MySQL全局锁和表锁

    最近正好在看操作系统中关于线程,锁的部分,也可以学习一下数据库种的锁. MySQL的锁分为全局锁,表级锁,行锁三类. 全局锁 名思义,全局锁就是对整个数据库实例加锁.MySQL提供了一个加全局读锁的方 ...

  2. mysql 全局锁_Mysql全局锁和表级锁

    以前对Mysql的锁的认识,只了解表锁和行锁,其实Mysql的锁的种类还是不少的,有全局锁,表级锁,行级锁,还有元数据锁,间隙锁,临界锁. 一 全局锁 Mysql的全局锁是对整个实例加锁,加锁之后,数 ...

  3. mysql默认使用悲观锁_mysql乐观锁和悲观锁详解

    mysql乐观锁和悲观锁详解 相信很多朋友在面试的时候,都会被问到乐观锁和悲观锁的问题,如果不清楚其概念和用法的情况下,相信很多朋友都会感觉很懵逼,那么面试的结果也就不言而喻了. 那么乐观锁和悲观锁到 ...

  4. mysql如何使用乐观锁_mysql 乐观锁和悲观锁

    数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的 ...

  5. mysql innodb默认的锁_Mysql InnoDB锁

    MySQL 不同引擎的锁机制: MyISAM和MEMORY采用表级锁(table-level locking) BDB采用页面锁(page-leve locking)或表级锁,默认为页面锁 InnoD ...

  6. mysql 事务排他锁_mysql排他锁

    1.排他锁示范: 排他锁:x锁,加完排他锁,事务不释放或者不提交,其他事务无法进行对应数据的操作(其他事务无法拿到对应的排他锁) -- 新建一个连接 select @@autocommit; set ...

  7. innodb 悲观锁 乐观锁_mysql乐观锁、悲观锁、共享锁、排它锁、行锁、表锁

    mysql乐观锁.悲观锁.共享锁.排它锁.行锁.表锁 乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使 ...

  8. mysql innodb 锁_MySQL/InnoDB锁机制

    显式加锁 select ... lock in share mode:加 S 锁 select ... for update:加 X 锁 MySQL快照读和当前读 在一个支持MVCC并发控制的系统中, ...

  9. mysql unique 锁_mysql 行锁排查

    mysql 锁表: 隔离级别使用RR: mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation; +----------------------- ...

最新文章

  1. -ms-,-moz-,-webkit-,-o-含义及各浏览器内核整理
  2. 推荐算法炼丹笔记:推荐系统采样评估指标及线上线下一致性问题
  3. 谁动了你的主机-Windows“唤醒”和“开机”时自动拍照-狩猎者项目
  4. Linux命令——cut命令学习
  5. [转载]博客园MetaWeblog使用帮助
  6. 如何让web控件FileUpload选择完文件之后就自动触发事件,让Image控件显示出图片来...
  7. Java中抽象类和接口的区别 经典(转)
  8. python判断是否有重复单词_Python:在字符串列表中查找未知的重复单词
  9. 饭客网络(基础教程)
  10. java 计算同比增长工具类
  11. 家用NAS有什么用?充分挖掘你的NAS功能
  12. JavaScript之document对象获取元素
  13. 支付宝支付 接口配置
  14. 软件测试应该何时介入项目?
  15. Hexo 个人博客绑定域名配置
  16. 听我一句劝,单片机不要去学STM32真的
  17. 顺序表与链表结构及解析
  18. 【状语从句练习题】综合训练
  19. jQuery是什么?
  20. word题注编号格式从仅数字顺序编号到包含章节号编号

热门文章

  1. java实现无序数组结构
  2. 工程项目管理需要注意哪些问题
  3. Oracle安装部署之RedHat安装Oracle11g_R2
  4. bootstrap 中这段代码 使bundles 失败
  5. vi and vim 用法
  6. 取重复记录最大的id列表
  7. 最佳子集aic选择_AutoML的起源:最佳子集选择
  8. 贝叶斯 朴素贝叶斯_手动执行贝叶斯分析
  9. covid 19如何重塑美国科技公司的工作文化
  10. 标记偏见_分析师的偏见