上一篇《mysql metadata lock(一)》介绍了为什么引入MDL,MDL作用以及MDL锁导致阻塞的几种典型场景,文章的最后还留下了一个小小的疑问。本文将更详细的介绍MDL,主要侧重介绍MDL的原理和实现。一般而言,商业数据库系统实现锁,一般将锁划分为读锁(共享锁)和写锁(排它锁),为了进一步提高并发性,还会加入意向共享锁和意向排它锁。但是偏偏mysql的MDL搞地比较复杂,但目的也是为了提高并发度。MDL包含有9种类型,详细参考表1。主要其实也是两大类,只是对共享锁做了进一步细分。

一、MDL的锁类型

锁名称

锁类型

说明

适用语句

MDL_INTENTION_EXCLUSIVE

共享锁

意向锁,锁住一个范围

任何语句都会获取MDL意向锁,

然后再获取更强级别的MDL锁。

MDL_SHARED

共享锁,表示只访问表结构

MDL_SHARED_HIGH_PRIO

共享锁,只访问表结构

show create table 等

只访问INFORMATION_SCHEMA的语句

MDL_SHARED_READ

访问表结构并且读表数据

select语句

LOCK TABLE ...  READ

MDL_SHARED_WRITE

访问表结构并且写表数据

SELECT ... FOR UPDATE

DML语句

MDL_SHARED_UPGRADABLE

可升级锁,访问表结构并且读写表数据

Alter语句中间过程会使用

MDL_SHARED_NO_WRITE

可升级锁,访问表结构并且读写表数据,并且禁止其它事务写。

Alter语句中间过程会使用

MDL_SHARED_NO_READ_WRITE

可升级锁,访问表结构并且读写表数据,并且禁止其它事务读写。

LOCK TABLES ... WRITE

MDL_EXCLUSIVE

写锁

禁止其它事务读写。

CREATE/DROP/RENAME TABLE等DDL语句。

                    表1

二、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锁,大部分情况都是线上出现异常了。那么出现异常后,我们如何去判断是MDL锁导致的呢。监视MDL锁主要有两种方法,一种是通过show  processlist命令,判断是否有事务处于“Waiting for table metadata lock”状态,另外就是通过mysql的profile,分析特定语句在每个阶段的耗时时间。

抛出几个问题:

  1. select 与alter是否会相互阻塞
  2. dml与alter是否会相互阻塞
  3. 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阶段。结合第一个和第二个问题,就可以回答《mysql metadata lock(一)》的疑问了。

第三个问题,显然,由于MDL_SHARED_WRITE与MDL_SHARED_READ兼容,所以它们不会因为MDL而导致等待的情况。具体例子和profile分析可以参考《mysql metadata lock(一)》。这里我们要考虑一个问题,LOCK TABLE ... READ上的MDL锁是MDL_SHARED_READ,而DML操作上的是MDL_SHARED_WRITE,那么前者和后者如何互斥?其实这个MDL是无能为力的,需要通过SERVER层的table lock来解,可以简单做一个实验,一个会话执行LOCK TABLE test READ,另外一个会话执行update test set xxx where id=xxx,会发现update语句堵塞,通过show processlist查看,状态为:"Waiting for table level lock"。但是如果使用LOCK TABLE test WRITE,则状态变为"Waiting for table metadata lock",其实此时table lock也是堵住的,只不过MDL在之前挡住了,这说明SERVER层的table lock和MDL在同时起作用。

mysql metadata lock(二)的更多相关文章

  1. mysql metadata lock(一)

    想必玩过mysql的人对Waiting for table metadata lock肯定不会陌生,一般都是进行alter操作时被堵住了,导致了我们在show processlist 时,看到线程的状 ...

  2. mysql metadata lock(三)

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

  3. mysql metadata lock锁

    很多情况下,很多问题从理论上或者管理上而言都是可以避免或者说很好解决的,但是一旦涉及到现实由于管理或者协调或者规范执行的不够到位,就会出现各种各样本不该出现的问题,这些问题的通常在生产环境并不会出现, ...

  4. 初步认知MySQL metadata lock(MDL)

    http://blog.itpub.net/26515977/viewspace-1208250/ 概述 随着5.5.3引入MDL,更多的Query被“Waiting for table metada ...

  5. mysql metadata lock

    想必玩过mysql的人对Waiting for table metadata lock肯定不会陌生,一般都是进行alter操作时被堵住了,导致了我们在show processlist 时,看到线程的状 ...

  6. MySQL Metadata Lock详解

    Metadata Lock 的作用: 要直接说出Metadata Lock 的作用.以我目前的文字功底是不行的.好在我可以通过一个例子来说明. 假设session 1 在正在执行如下的SQL语句 se ...

  7. Metadata Lock原理5

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

  8. MySQL出现Waiting for table metadata lock的原因以及解决方法

    转自:http://ctripmysqldba.iteye.com/blog/1938150 (有修改) MySQL在进行alter table等DDL操作时,有时会出现Waiting for tab ...

  9. 【转】【MySql】Waiting for table metadata lock原因分析

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

随机推荐

  1. SSH框架执行自己定义的SQL语句

    直接上代码 String hsql = "delete XTable x where x.Userid= ?"; Query query = this.getSession().c ...

  2. 【Java每日一题】20161028

    package Oct2016; public class Ques1028 { public static void main(String[] args){ new B().out(); // 输 ...

  3. webservice入门(1)

    前段时间学习了webservice的用法,虽然只是一些简单的用法,但是如果久了还是会忘记的,所以将学到了记录下来. 一:schema和http协议. 1.schema约束: schema规范中: . ...

  4. 调优Java virtual machine常见问题汇总整理

    数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本身, ...

  5. Java基础学习 -- Java(OOP)程序的设计原则

    避免代码复制.解决方案:函数.父类: 封装.尽量private每个类的成员变量,用操作封装数据,减少类与类之间成员变量的直接调用,而是调用method,降低耦合: 可扩展性最大化.尽量使用框架+数据的 ...

  6. oracle RAC的VIP和scan

    我们都知道Oracle RAC中每个节点都有一个虚拟IP,简称VIP,与公网IP在同一个网段. 没有VIP时,Oracle客户端是靠"TCP/IP协议栈超时"来判断服务器故障.而T ...

  7. Ouibounce – 在用户离开你网站时显示模态弹窗

    Ouibounce 是一个微小的库,用于实现在用户离开你的网站的时候显示一个模式窗口.这个库可以帮助你增加着陆页的转换率. Ouibounce 会在当鼠标光标移动到接近(或通过)视口(viewport ...

  8. 前端上传组件Plupload使用指南

    我之前写过一篇文章<文件上传利器SWFUpload使用指南>,里面介绍了上传组件SWFUpload的使用方法,但现在随着html5技术的逐渐推广和普及,再去使用以flash为上传手段的SW ...

  9. 众人口中的JAVASCRIPT

    目前所说的JAVASCRIPT=ECMAscript+DOM+BOM DOM全称:Document Object Model,造作网页内容的标准. BOM全称:Browse Object Model, ...

  10. javascript 图片淡入淡出效果 实例源代码

    代码说明:把代码粘贴好之后,需要更改html代码中的图片路径,即可执行成功.后面还有对js代码的详细说明,希望大家好好消化,好好理解. html源代码: <head> <title& ...