当我们在 MySQL 中执行 DDL 语句时,经常会发现语句没有在你预期的时间完成,这时候我们通常会使用 show full processlist ,来看看发生了什么状况。当你看到 waiting for table metadata lock 时,那就碰到元数据锁了。那元数据锁是怎样产生的又应该怎样避免呢?让我们从这篇文章开始了解它。
1、什么是元数据锁
MDL 全称为 metadata lock,即元数据锁,一般也可称为字典锁。MDL 的主要作用是为了管理数据库对象的并发访问和确保元数据一致性。元数据锁适用对象包含:table、schema、procedures, functions, triggers, scheduled events、tablespaces 。
2、加锁规则
获取规则:
3、模拟加锁规则
两个相同表结构的表 t 和 t_new 开始。三个线程来操作这些表:
场景一
线程 1:
- LOCK TABLE t WRITE, t_new WRITE;
该语句按表名顺序在 t 和 t_new 上获取写锁
线程 2:
- INSERT INTO t VALUES(1);
该语句处于也需要获取表 t 上的 MDL 所以处于等待状态
线程 3:
- RENAME TABLE t TO t_old, t_new TO t;
该语句需要按表名顺序在 t 、t_new、t_old 上获取互斥锁,所以也处于等待状态
线程 1:
- UNLOCK TABLES;
该语句释放对 t 和 t_new 的写锁定。线程 3 对 t 加写锁的优先级高于 线程 2 ,因此线程 3 在 t 上优先获得互斥锁,然后依次在 t_new、t_old 上获取互斥锁,执行重命名后释放其锁定。线程 2 获得 t 上的写锁,执行插入操作,然后释放其锁定。rename 操作在 insert 之前执行。
场景二
两个具有相同表结构的表 t 和 new_t ,同样是三个线程来操作这些表
线程 1:
- LOCK TABLE t WRITE, new_t WRITE;
该语句按表名顺序在 new_t 和 t 上获取写锁
线程 2:
- INSERT INTO t VALUES(1);
该语句处于也需要获取表 t 上的 MDL 所以处于等待状态
线程 3:
- RENAME TABLE t TO old_t, new_t TO t;
该语句需要按表名顺序在 new_t 、old_t、t 上获取互斥锁,所以也处于等待状态
该语句释放对 t 和 new_t 的写锁定。对于 t 首先发起锁请求的是线程 2 ,因此线程 2 优先获得了 t 上的元数据写锁,执行完插入操作,然后释放该锁。线程 3 首先获取的是 new_t 、old_t 的互斥锁,最后才会请求 t 上的互斥锁,所以线程 3 在线程 2 执行完毕之前都是处于等待状态的。rename 操作在 insert 操作之后。
4、 如何监控元数据锁
performance_schema.metadata_locks 表中记录了元数据锁相关的信息,开启方式如下:在线开启 metadata_locks,操作如下:
- --UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME ='global_instrumentation';
- --此值默认已开启了,可检查确认。
- UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME ='wait/lock/metadata/sql/mdl';
若可停库维护,则在 my.cnf 中添加如下:
- [mysqld]
- performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'
5、如何优化元数据锁
MDL 锁一旦发生会对业务造成极大影响,因为后续所有对该表的访问都会被阻塞,造成连接积压。我们日常要尽量避免 MDL 锁的发生,下面给出几点优化建议可供参考:
CKeditor,以前叫FCKeditor,已经使用过好多年了,功能自然没的说。最近升级到3....
本文实例讲述了AJAX+Servlet实现的数据处理显示功能。分享给大家供大家参考,具...
来源:DeepenStudy 漏洞文件:js.asp % Dimoblog setoblog=newclass_sys oblog.a...
大家好,我是狂聊君。 今天来聊一聊 Mysql 缓存池原理。 提纲附上,话不多说,直...
idea官方推送了2020.2.4版本的更新,那么大家最关心的问题来了,之前激活idea202...
在Flash Player 10.1及以上版本中,adobe新增了全局错误处理程序UncaughtErrorEv...
本文转载自微信公众号「SH的全栈笔记」,作者SH。转载本文请联系SH的全栈笔记公...
前言 项目开发中不管是前台还是后台都会遇到烦人的null,数据库表中字段允许空值...
本文转载自微信公众号「SQL数据库」,作者丶平凡世界 。转载本文请联系开发公众...
问题:我们在做flex的开发中,如果用到别人搭建好的框架,而别人的server名称往...