一 简介 
  上一篇文章 《MetaData Lock 之一》  简单的介绍了MySQL 引入MDL 的前因后果,本文深入了解MDL的实现原理和运行机制。
二 MDL 的类型
  metadata lock也是一种锁。每个metadata lock都会定义锁住的对象,锁的持有时间和锁的类型。
2.1 按照对象/范围划分

属性 含义 范围/对象
GLOBAL 全局锁 范围
COMMIT 提交保护锁 范围
SCHEMA 库锁 对象
TABLE 表锁 对象
FUNCTION 函数锁 对象
PROCEDURE 存储过程锁 对象
TRIGGER 触发器锁 对象
EVENT 事件锁 对象

MDL按锁住的对象来分类,可以分为global,commit,schema, table, function,procedure,trigger,event,这些对象发生锁等待时,我们在show processlist可以分别看到如下等待信息。

  1. Waiting for global read lock
  2. Waiting for commit lock
  3. Waiting for schema metadata lock
  4. Waiting for table metadata lock
  5. Waiting for stored function metadata lock
  6. Waiting for stored procedure metadata lock
  7. Waiting for trigger metadata lock
  8. Waiting for event metadata lock

2.2 按照锁的持有时间

属性 含义
MDL_STATEMENT 从语句开始执行时获取,到语句执行结束时释放。
MDL_TRANSACTION 在一个事务中涉及所有表获取MDL,一直到事务commit或者rollback(线程中终清理)才释放。
MDL_EXPLICIT 需要MDL_context::release_lock()显式释放。
语句或者事务结束,也仍然持有,如
Lock table, flush .. with lock语句等。

2.3 按照操作的对象

属性 含义 事例
MDL_INTENTION_EXCLUSIVE(IX) 意向排他锁用于global和commit的加锁。 truncate table t1;
insert into t1 values(3,'abcde');会加如下锁(GLOBAL,MDL_STATEMENT,MDL_INTENTION_EXCLUSIVE)                            (SCHEMA,MDL_TRANSACTION,MDL_INTENTION_EXCLUSIVE)

MDL_SHARED(S) 只访问元数据 比如表结构,不访问数据。 set golbal_read_only =on 加锁
(GLOBAL,MDL_EXPLICIT,MDL_SHARED)
MDL_SHARED_HIGH_PRIO(SH) 用于访问information_scheam表,不涉及数据。 select * from information_schema.tables;
show create table xx; desc xxx;会加如下锁:
(TABLE,MDL_TRANSACTION,MDL_SHARED_HIGH_PRIO)
MDL_SHARED_READ(SR) 访问表结构并且读表数据 select * from t1; lock table t1 read;
会加如下锁:
(TABLE,MDL_TRANSACTION,MDL_SHARE_READ)
MDL_SHARED_WRITE(SW) 访问表结构并且写表数据 insert/update/delete/select .. for update
会加如下锁:
(TABLE,MDL_TRANSACTION,MDL_SHARE_WRITE)
MDL_SHARED_UPGRADABLE(SU) 是mysql5.6引入的新的metadata lock,
在alter table/create index/drop index会加该锁;可以说是为了online ddl才引入的。特点是允许DML,防止DDL;
(TABLE,MDL_TRANSACTION,MDL_SHARED_UPGRADABLE)
MDL_SHARED_NO_WRITE(SNW) 可升级锁,访问表结构并且读写表数据,并且禁止其它事务写。 alter table t1 modify c bigint;(非onlineddl)
(TABLE,MDL_TRANSACTION,MDL_SHARED_NO_WRITE)
MDL_SHARED_NO_READ_WRITE(SNRW) 可升级锁,访问表结构并且读写表数据,并且禁止其它事务读写。 lock table t1 write;加锁
(TABLE,MDL_TRANSACTION,MDL_SHARED_NO_READ_WRITE
MDL_EXCLUSIVE(X) 防止其他线程读写元数据 CREATE/DROP/RENAME TABLE,其他online DDL在rename阶段也持有X锁
(TABLE,MDL_TRANSACTION,MDL_EXCLUSIVE)

关于global对象
   主要作用是防止DDL和写操作的过程中,执行set golbal_read_only =on或flush tables with read lock;
 关于commit对象锁
  主要作用是执行flush tables with read lock后,防止已经开始在执行的写事务提交。
  insert/update/delete在提交时都会上(COMMIT,MDL_EXPLICIT,MDL_INTENTION_EXCLUSIVE)锁。

 

2.4 MDL 锁的兼容性矩阵

三、几种典型语句的加(释放)锁流程
1.select语句操作MDL锁流程
   1)Opening tables阶段,加共享锁
     a)   加MDL_INTENTION_EXCLUSIVE锁
     b)   加MDL_SHARED_READ锁
   2)事务提交阶段,释放MDL锁
     a)   释放MDL_INTENTION_EXCLUSIVE锁
     b)   释放MDL_SHARED_READ锁
2. DML语句操作MDL锁流程
  1)Opening tables阶段,加共享锁
     a)   加MDL_INTENTION_EXCLUSIVE锁
     b)   加MDL_SHARED_WRITE锁
  2)事务提交阶段,释放MDL锁
     a)   释放MDL_INTENTION_EXCLUSIVE锁
     b)   释放MDL_SHARED_WRITE锁
3. alter操作MDL锁流程
  1)Opening tables阶段,加共享锁
     a)   加MDL_INTENTION_EXCLUSIVE锁
     b)   加MDL_SHARED_UPGRADABLE锁,升级到MDL_SHARED_NO_WRITE锁
  2)操作数据,copy data,流程如下:
     a)   创建临时表tmp,重定义tmp为修改后的表结构
     b)   从原表读取数据插入到tmp表
  3)将MDL_SHARED_NO_WRITE读锁升级到MDL_EXCLUSIVE锁
     a)   删除原表,将tmp重命名为原表名
  4)事务提交阶段,释放MDL锁
     a)   释放MDL_INTENTION_EXCLUSIVE锁
     b)   释放MDL_EXCLUSIVE锁

四、典型问题分析
通常情况下我们关注MDL锁,大部分情况都是线上DB出现异常了。那么出现异常后,我们如何去判断是MDL锁导致的呢。监视MDL锁主要有两种方法,一种是通过show  processlist命令,判断是否有事务处于“Waiting for table metadata lock”状态,另外就是通过mysql的profile,分析特定语句在每个阶段的耗时时间。
抛出几个问题:
select 与alter是否会相互阻塞
dml与alter是否会相互阻塞
select与DML是否会相互阻塞
结合第三节几种语句的上锁流程,我们很容易得到这三个问题的答案。语句会在阻塞在具体某个环节,可以通过profile来验证我们的答案是否正确。
第一个问题,当执行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飙高的情况。
第二个问题,alter在opening阶段会将锁升级到MDL_SHARED_NO_WRITE,rename阶段再将升级为MDL_EXCLUSIVE,由于MDL_SHARED_NO_WRITE与MDL_SHARED_WRITE互斥,所以先执行alter或先执行DML语句,都会导致语句阻塞在opening tables阶段。
第三个问题,显然,由于MDL_SHARED_WRITE与MDL_SHARED_READ兼容,所以它们不会因为MDL而导致等待的情况。

五 参考资料
 [1] 《MDL 锁介绍二 》他的三篇文章都值得一读,强烈推荐,本系列文章也是参考他的blog 写的。
 [2] 《DDL操作导致备库复制中断》 @印风的blog 为alisql/RDS 打了N多patch的牛人。

Metadata Lock原理6的更多相关文章

  1. Metadata Lock原理5

    [MySQL] 之一2015-09-05 15:46:51 分类: MySQL 一 简介 和MySQL打交道比较多的朋友,肯定遇到过 "Waiting for table metadata ...

  2. Metadata Lock原理4

     http://blog.chinaunix.net/uid-28212952-id-3400571.html    Alibaba  今天发生一个故障,MM复制结构(主备库),备库slave del ...

  3. Metadata Lock原理8

    http://www.kancloud.cn/taobaomysql/monthly/67141 MySQL· 5.7优化·Metadata Lock子系统的优化 背景 引入MDL锁的目的,最初是为了 ...

  4. Metadata Lock原理7

    http://blog.itpub.net/22664653/viewspace-1791744/ 一 简介 通过前面两篇文章的介绍,相信读到这里的各位对MDL 锁已经有了比较深入的了解了,本文将结合 ...

  5. Metadata Lock原理3

      http://blog.itpub.net/26515977/viewspace-1208250/   腾讯工程师 随着5.5.3引入MDL,更多的Query被“Waiting for table ...

  6. Metadata Lock原理2

    同事说开发机更改一个表结构,加字段,但是一直挂在那里,没反应.一开始以为表测试数据量很大,因为mysql增加表字段会重写表,后来看了下数据量很小,就另外查看过程.原因分析和处理如下:  一.环境  m ...

  7. Metadata Lock原理1

    https://www.percona.com/blog/2013/02/01/implications-of-metadata-locking-changes-in-mysql-5-5/ impli ...

  8. mysql metadata lock(三)

    前言 MDL锁主要用来保护Mysql内部对象的元数据,通过MDL机制保证DDL与DML以及SELECT查询操作的并发.MySQL Meta Lock(一)和MySQL Meta Lock(二)已经讲了 ...

  9. mysql metadata lock(二)

    上一篇<mysql metadata lock(一)>介绍了为什么引入MDL,MDL作用以及MDL锁导致阻塞的几种典型场景,文章的最后还留下了一个小小的疑问.本文将更详细的介绍MDL,主要 ...

随机推荐

  1. linux 安装jdk 配置tomcat

    Linux(ubuntu)下安装JDK.Tomcat 一.安装jdk 1)首先以root用户登录进去,在根目录下建立/usr/java的目录,我们将下载的东西都放到该目录下去. 2)参考的https: ...

  2. 【转】OFBiz安全组

    安全组标识 描述 用户系统级别BIZADMIN 全部商业应用程序权限组,具有全部商业应用程序管理权限,不是技术人员权限. bizadmin FLEXADMIN 缓存管理组,具有全部颗粒的权限. fle ...

  3. bjfu1235 两圆公共面积

    给定两个圆,求其覆盖的面积,其实也就是求其公共面积(然后用两圆面积和减去此值即得最后结果). 我一开始是用计算几何的方法做的,结果始终不过.代码如下: /* * Author : ben */ #in ...

  4. Windows7 64位系统下无法安装网络打印机的解决方法

    背景: 公司一台HP LaserJet 1010 打印机连在一台Windows XP的电脑上,而我的是windows7 64位系统,无法安装驱动解决办法:1:去惠普官网上下载对应的64位驱动(什么Vi ...

  5. Python之正则

    从学习Python至今,发现很多时候是将Python作为一种工具.特别在文本处理方面,使用起来更是游刃有余. 说到文本处理,那么正则表达式必然是一个绝好的工具,它能将一些繁杂的字符搜索或者替换以非常简 ...

  6. Python 学习笔记(四)正则、闭合、生成器

    (一)正则表达式 基本规则: ^ 匹配字符串开始位置. $ 匹配字符串结束位置. \b 匹配一个单词边界. \d 匹配一个数字. \D 匹配一个任意的非数字字符. x? 匹配可选的x字符.换句话说,就 ...

  7. 批量ping主机脚本

    #! /bin/bash for i in `cat test.list`do   host=`echo $i|awk -F"," '{print $1}'`   app_IP=` ...

  8. Web Service学习之一:Web Service原理

    一.定义 Web Service 不是框架也不是技术 而是解决远程调用.跨平台调用.跨语言调用问题的一种规范. 二.应用1.同一个公司新.旧系统的整合:比如CRM系统与OA.客服系统相互调用2.不同公 ...

  9. POJ 1611 The Suspects (并查集)

    The Suspects 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/B Description 严重急性呼吸系统综合症( S ...

  10. uniPanel特效

    function beforeInit(sender){ sender.layout='accordion'; Ext.apply (sender, {title:'供应链',style:'text- ...