mysql metadata lock(二)
上一篇《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,分析特定语句在每个阶段的耗时时间。
抛出几个问题:
- 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阶段。结合第一个和第二个问题,就可以回答《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(二)的更多相关文章
- mysql metadata lock(一)
想必玩过mysql的人对Waiting for table metadata lock肯定不会陌生,一般都是进行alter操作时被堵住了,导致了我们在show processlist 时,看到线程的状 ...
- mysql metadata lock(三)
前言 MDL锁主要用来保护Mysql内部对象的元数据,通过MDL机制保证DDL与DML以及SELECT查询操作的并发.MySQL Meta Lock(一)和MySQL Meta Lock(二)已经讲了 ...
- mysql metadata lock锁
很多情况下,很多问题从理论上或者管理上而言都是可以避免或者说很好解决的,但是一旦涉及到现实由于管理或者协调或者规范执行的不够到位,就会出现各种各样本不该出现的问题,这些问题的通常在生产环境并不会出现, ...
- 初步认知MySQL metadata lock(MDL)
http://blog.itpub.net/26515977/viewspace-1208250/ 概述 随着5.5.3引入MDL,更多的Query被“Waiting for table metada ...
- mysql metadata lock
想必玩过mysql的人对Waiting for table metadata lock肯定不会陌生,一般都是进行alter操作时被堵住了,导致了我们在show processlist 时,看到线程的状 ...
- MySQL Metadata Lock详解
Metadata Lock 的作用: 要直接说出Metadata Lock 的作用.以我目前的文字功底是不行的.好在我可以通过一个例子来说明. 假设session 1 在正在执行如下的SQL语句 se ...
- Metadata Lock原理5
[MySQL] 之一2015-09-05 15:46:51 分类: MySQL 一 简介 和MySQL打交道比较多的朋友,肯定遇到过 "Waiting for table metadata ...
- MySQL出现Waiting for table metadata lock的原因以及解决方法
转自:http://ctripmysqldba.iteye.com/blog/1938150 (有修改) MySQL在进行alter table等DDL操作时,有时会出现Waiting for tab ...
- 【转】【MySql】Waiting for table metadata lock原因分析
MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...
随机推荐
- .Net在线付款---Paypal在线付款开发过程
原文:.Net在线付款---Paypal在线付款开发过程 最近在做一个Web订单项目,项目有一个需求就是集成Paypal与Paydollar在线付款,一开始看到这个需求也是傻了眼,因为以前从来没有做过 ...
- EC笔记,第一部分:2.尽量以const,enum,inline代替#define
02.尽量以const,enum,inline代替#define 原因:编译前的预处理会替换宏,所以调试的时候找不到错误 1.const 尽量用const替代常量宏定义 两种特殊情况: (1).常量指 ...
- PHP组件化开发
设计思想中有两种极端:大而全.小而美. 一般我们常用的库是小而美,用的框架是大而全.从Symfony实现Component式开发开始,框架的组件化逐渐成为趋势.我们可以任意的组合各种Compoent来 ...
- Time series database
https://en.wikipedia.org/wiki/Time_series_database https://influxdb.com/docs/v0.9/introduction/getti ...
- 求助,eclipse总是卡在building workspace-CSDN论坛
1).解决方法 方法1.修改eclipse启动文件 eclipse.ini 中添加启动参数参数: -vmargs -Xmx512m 方法2.关闭自动构建工作区: project -> build ...
- 算法:冒泡排序(python版)
1.将n个元素从大到小排序后,选择第k个大的元素 #!/usr/bin/env python #coding -*- utf:8 -*- #冒泡排序选第k个元素 import random impor ...
- GJM : Python简单爬虫入门(二) [转载]
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- 一行代码调用实现带字段选取+条件判断+排序+分页功能的增强ORM框架
问题:3行代码 PDF.NET是一个开源的数据开发框架,它的特点是简单.轻量.快速,易上手,而且是一个注释完善的国产开发框架,受到不少朋友的欢迎,也在我们公司的项目中多次使用.但是,PDF.NET比起 ...
- 已解决:Ubuntu php gettext 无效
使用gettext做多文字国际化,按PHP官方文档,在CentOS上OK,在Ubuntu上不行,调试了快1天,试了网上提供的无数方法,终于有一个OK了…… 看到此文的同学别再被坑了…… 感谢:http ...
- 25个有用的和方便的 WordPress 速查手册
如果你是 WordPress 开发人员,下载一些方便的 WordPress 备忘单可以在你需要的时候快速查找.下面这个列表,我们已经列出了25个有用的和方便的 WordPress 速查手册,赶紧收藏吧 ...