Metadata Lock原理7
通过前面两篇文章的介绍,相信读到这里的各位对MDL 锁已经有了比较深入的了解了,本文将结合理论知识介绍几组MDL 锁的案例。
二 常见MDL 锁的场景
1 Waiting for global read lock
我们先构造一个Waiting for global read lock场景:
session1: alter table t1 add c3 bigint; //大表执行需较长时间
session2: set global read only=on; //等待
查看
- mysql> show processlist;
- +----+------+-----------------+------+---------+------+------------------------------+------------------------------+
- | Id | User | Host | db | Command | Time | State | Info |
- +----+------+-----------------+------+---------+------+------------------------------+------------------------------+
- | 1 | root | localhost:5202 | test | Query | 12 | altering table | alter table t1 add c3 bigint |
- | 2 | root | localhost:14699 | test | Query | 3 | Waiting for global read lock | set global read_only=on |
- | 3 | root | localhost:17085 | NULL | Query | 0 | init | show processlist |
- +----+------+-----------------+------+---------+------+------------------------------+------------------------------+
分析:
alter table t1 add c3 bigint;会加(GLOBAL,MDL_STATEMENT,MDL_INTENTION_EXCLUSIVE) 语句结束后才释放
set global read only=on; 会加(GLOBAL,MDL_EXPLICIT,MDL_SHARED)
由于session1执行时间比较长,一直持有MDL_INTENTION_EXCLUSIVE。从兼容性矩阵可以看出MDL_SHARED和MDL_INTENTION_EXCLUSIVE是不相容的,因此发生“Waiting for global read lock ”等待。直到session 1 alter操作完成释放MDL_INTENTION_EXCLUSIVE。set global read only=on;才可以继续执行。
2.2 Waiting for commit lock
session1:
begin;
insert into t1 vlaues(null, 'ab');
session2:
flush table with read lock;//成功
session1: commit //发生等待
mysql> show processlist;
- +----+------+-----------------+------+------------+------+-------------------------+------------------+
- | Id | User | Host | db | Command | Time | State | Info |
- +----+------+-----------------+------+------------+------+-------------------------+------------------+
- | 1 | root | 127.0.0.1:5202 | test | Query | 7 | Waiting for commit lock | commit |
- | 2 | root | 127.0.0.1:14699 | test | Sleep | 13 | | NULL |
- | 3 | root | 127.0.0.1:17085 | NULL | Query | 0 | init | show processlist |
- +----+------+-----------------+------+---------+------+-------------------------+------------------+
分析:
flush table with read lock;持有(COMMIT,MDL_EXPLICIT,MDL_SHARED)
commit时上(COMMIT,MDL_EXPLICIT,MDL_INTENTION_EXCLUSIVE)锁
MDL_SHARED和MDL_INTENTION_EXCLUSIVE是不相容的,因此发生等待.
2.3 Waiting for table metadata lock
这个是比较常见的锁等待,总结下来有如下几种场景
1 长查询/mysqldump 阻塞DDL
| session1 | session2 | session3 |
| Select count(*) from t; | ||
| alter table t add column c3 int; |
||
| Show processlist; session2:copy to tmp table |
||
| 阻塞 | Show processlist; session2:Waiting for table metadata lock |
|
| A:执行完毕 | ||
| Show processlist; session2:rename table |
||
| Select count(*) from t; | ||
| B:执行完毕 | ||
| Show processlist; session1: Sending data |
||
会话1先执行select ,会话2后执行alter,在会话1执行完毕前,会话2拿不到MDL锁,从表格上面来看,主要阻塞在rename阶段。会话1在执行完毕后,会话2拿到MDL锁,变为rename table状态,这个操作持续时间非常短,会话1再次执行查询,当会话2执行完后,此时会话1正常执行。这说明对于MDL锁而言,select会阻塞alter,而alter不会阻塞select。在rename的瞬间,alter是会阻塞select的.
当执行select语句时,只要select语句在获取MDL_SHARED_READ锁之前,alter没有执行到rename阶段,那么select获取MDL_SHARED_READ锁成功,后续有alter执行到rename阶段,请求MDL_EXCLUSIVE锁时,就会被阻塞。rename阶段会持有MDL_EXCLUSIVE锁,但由于这个过程时间非常短(大头都在copy数据阶段),并且是alter的最后一个阶段,所以基本感觉不到alter会阻塞select语句。由于MDL锁在事务提交后才释放,若线上存在大查询,或者存在未提交的事务,则会出现ddl卡住的现象。这里要注意的是,ddl卡住后,若再有select查询或DML进来,都会被堵住,就会出现threadrunning飙高的情况。
2 未提交的事务阻塞 DDL
| session1 | session2 | session3 |
| begin; update t set where id=3; |
||
| alter table t add column c3 int;//hang |
||
| Show processlist; session2:Waiting for table metadata lock |
||
| Select count(*) from t;//hang | ||
| Show processlist; session2:Waiting for table metadata lock session3:Waiting for table metadata lock |
session1 对表t进行update操作,存在未提交的事务,故一直持有 MDL_SHARED_WRITE锁,由于没有执行COMMIT,会一直持有。session2 DDL 操作会请求TABLE-TRANSACTION-EXCLUSIVE锁,该锁与session1 的MDL_SHARED_WRITE 锁互斥,故 session2 的DDL 等待;session3的查询操作会请求TABLE- TRANSACTION- MDL_SHARED_READ锁,虽然MDL_SHARED_READ与活跃锁MDL_SHARED_WRITE不冲突,但是与session2的等待锁EXCLUSIVE冲突,因此也会等待。
解决该中场景的问题比较麻烦,但从show processlist 不能检查出哪个会话持有锁 。可以从两个方面进行调查
a 查询 information_schema.innodb_trx

b 检查 show engine innodb status ;

active N sec 说明事务持续了N秒,一般而言超过10秒的事务都是有问题的 。找到了活动的事务之后,要和开发沟通看看如何处理,能否直接kill 该回话? 根据和开发沟通的结果采取相应的措施。
3 第1种情况的特例,存在一个查询失败的语句,比如查询不存在的列,语句失败返回,但是事务没有提交,此时alter仍然会被堵住。
通过show processlist看不到TableA上有任何操作,在information_schema.innodb_trx中也没有任何进行中的事务。这很可能是因为在一个显式的事务中,对TableA进行了一个失败的操作(比如查询了一个不存在的字段),这时事务没有开始,但是失败语句获取到的锁依然有效。从performance_schema.events_statements_current表中可以查到失败的语句。
官方手册上对此的说明如下:
If the server acquires metadata locks for a statement that is syntactically valid but fails during execution, it does not release the locks early. Lock release is still deferred to the end of the transaction because the failed statement is written to the binary log and the locks protect log consistency.
也就是说除了语法错误,其他错误语句获取到的锁在这个事务提交或回滚之前,仍然不会释放掉。because the failed statement is written to the binary log and the locks protect log consistency 但是解释这一行为的原因很难理解,因为错误的语句根本不会被记录到二进制日志。
三 参考
[1] 《MySQL出现Waiting for table metadata lock的场景浅析》
[2] 《MySQL中 metadata lock问题分析》
[3] 《官方Metadata Lock 介绍》
Metadata Lock原理7的更多相关文章
- Metadata Lock原理6
一 简介 上一篇文章 <MetaData Lock 之一> 简单的介绍了MySQL 引入MDL 的前因后果,本文深入了解MDL的实现原理和运行机制.二 MDL 的类型 meta ...
- Metadata Lock原理5
[MySQL] 之一2015-09-05 15:46:51 分类: MySQL 一 简介 和MySQL打交道比较多的朋友,肯定遇到过 "Waiting for table metadata ...
- Metadata Lock原理4
http://blog.chinaunix.net/uid-28212952-id-3400571.html Alibaba 今天发生一个故障,MM复制结构(主备库),备库slave del ...
- Metadata Lock原理8
http://www.kancloud.cn/taobaomysql/monthly/67141 MySQL· 5.7优化·Metadata Lock子系统的优化 背景 引入MDL锁的目的,最初是为了 ...
- Metadata Lock原理3
http://blog.itpub.net/26515977/viewspace-1208250/ 腾讯工程师 随着5.5.3引入MDL,更多的Query被“Waiting for table ...
- Metadata Lock原理2
同事说开发机更改一个表结构,加字段,但是一直挂在那里,没反应.一开始以为表测试数据量很大,因为mysql增加表字段会重写表,后来看了下数据量很小,就另外查看过程.原因分析和处理如下: 一.环境 m ...
- Metadata Lock原理1
https://www.percona.com/blog/2013/02/01/implications-of-metadata-locking-changes-in-mysql-5-5/ impli ...
- mysql metadata lock(三)
前言 MDL锁主要用来保护Mysql内部对象的元数据,通过MDL机制保证DDL与DML以及SELECT查询操作的并发.MySQL Meta Lock(一)和MySQL Meta Lock(二)已经讲了 ...
- mysql metadata lock(二)
上一篇<mysql metadata lock(一)>介绍了为什么引入MDL,MDL作用以及MDL锁导致阻塞的几种典型场景,文章的最后还留下了一个小小的疑问.本文将更详细的介绍MDL,主要 ...
随机推荐
- C#发送Email邮件(实例:QQ邮箱和Gmail邮箱)
下面用到的邮件账号和密码都不是真实的,需要测试就换成自己的邮件账号. 需要引用: using System.Net.Mail; using System.Text; using System.Net; ...
- 在window server 2008 64位系统上 发布网站的过程中遇到的问题(转)
发布网站的过程如下: 1.安装数据库系统2.建立数据库,执行sql3.安装iis4.在本地机子上发布网站5.把发布好的东西拷贝到IIS上 1.安装数据库系统: 出现错误:必须使用角色管理工具 安装或配 ...
- awk简单使用『摘.非原创』
1 awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是lin ...
- (原创)LAMP教程3-下载centos6.4
(原创)LAMP教程3-下载centos6.4 今天我要给大家讲的是安装CentOS-6.4-x86_64,是的没有错,就是64位的,因为我的机子是4G的内存,安装64位的centos是绰绰有余啊,但 ...
- codeforces 687B - Remainders Game 数学相关(互质中国剩余定理)
题意:给你x%ci=bi(x未知),是否能确定x%k的值(k已知) ——数学相关知识: 首先:我们知道一些事情,对于k,假设有ci%k==0,那么一定能确定x%k的值,比如k=5和ci=20,知道x% ...
- 差分信号(Differential Signal)
差分信号(Differential Signal)在高速电路设计中的应用越来越广泛,电路中最关键的信号往往都要采用差分结构设计,什么另它这么倍受青睐呢?在 PCB 设计中又如何能保证其良好的性能呢? ...
- 双nginx(主备、主主)反向代理tomcat实现web端负载均衡
经过以前做完的产品,受前公司几位前辈技术大拿指点,来自己动手实现并总结一下web端的负载解决方法,高手请略过,个人认知有限,请各位指正错误. 下面是结构图: 我的系统环境是Fedora22(适用rea ...
- 机器学习真的可以起作用吗?(3)(以二维PLA为例)
前两篇文章已经完成了大部分的工作,这篇文章主要是讲VC bound和 VC dimension这两个概念. (一)前文的一点补充 根据前面的讨论,我们似乎只需要用来替代来源的M就可以了,但是实际公式却 ...
- DRAM 内存介绍(一)
转载自博客大神迈克老狼的blog: http://www.cnblogs.com/mikewolf2002/archive/2012/11/13/2768804.html 参考资料:http://ww ...
- HTML编码
JavaScript encodeURI() 函数 JavaScript encodeURIComponent() 函数 1.encodeURI: 不编码字符① - _ * . ! ~ ' ( ) ; ...