前言

MDL锁主要用来保护Mysql内部对象的元数据,通过MDL机制保证DDL与DML以及SELECT查询操作的并发。MySQL Meta Lock(一)MySQL Meta Lock(二)已经讲了一些关于MDL知识,本文将会对MDL进行一个补充,并解释查询堵塞和mysqldump获取一致性备份的原理。

一、MDL锁类型

1.按类型划分

参见MySQL Meta Lock(二)

2.按对象/范围维度划分

属性

含义

范围/对象

GLOBAL

全局锁

范围

COMMIT

提交保护锁

范围

SCHEMA

库锁

对象

TABLE

表锁

对象

FUNCTION

函数锁

对象

PROCEDURE

存储过程锁

对象

TRIGGER

触发器锁

对象

EVENT

事件锁

对象

MDL锁主要包括DB对象和范围两个维度,对象的MDL我们很好理解,为了保护对象的元数据。那么范围级别的锁呢?锁本质是为了保护共享资源,所以范围和对象都可以理解为一种资源。MYSQL约定某些操作必需要上COMMIT范围锁或GLOBAL范围锁,通过这种同步机制,保证各个线程有序运转。后面会结合案例详细讨论COMMIT和GLOBAL锁的应用场景。

3.按请求/释放锁持续时间划分

属性

含义

MDL_ STATEMENT

语句级别

MDL_TRANSACTION

事务级别

MDL_EXPLICIT

需要显示释放

MDL另外一个属性是持有时间。如果是STATEMENT,则表示单个语句执行完毕后,MDL释放;TRANSACTION级别表示,事务结束后,MDL锁释放;前两者都是隐式锁,即请求锁和释放锁都是系统内部行为,用户无需发指令,而MDL_EXPLICIT表示MDL锁是显示请求和释放的。比如:flush table with read lock这个指令会显示上GLOBAL:MDL_EXPLICIT:SHARED和COMMIT:MDL_EXPLICIT:SHARED锁;需要通过UNLOCK TABLES指令显示释放。

4.范围锁的兼容性矩阵

5.举个栗子

begin:

update t3 set c1=1 where id=1;

commit;

流程

执行语句

执行内容

字典锁

1

begin

释放MDL

release_transactional_locks

2

update t3 set c1=1 where id=1;

请求

STATEMENT  MDL

GLOBAL:STATMENT

MDL_INTENTION_EXCLUSIVE

3

请求

TRANSACTION MDL

TABLE:TRANSACTION

MDL_SHARED_WRITE

6

执行更新

7

释放

STATEMENT MDL

GLOBAL:STATMENT

8

commit;

请求

COMMIT MDL

COMMIT: MDL_EXPLICIT

MDL_INTENTION_EXCLUSIVE

9

执行提交

11

释放

COMMIT MDL

释放

TRANSACTION MDL

COMMIT: MDL_EXPLICIT

MDL_INTENTION_EXCLUSIVE

12

release_transactional_locks

TABLE:TRANSACTION

二、请求锁/释放锁原理

锁兼容矩阵在metadata lock(二)已经有详细的介绍,仔细看代码发现MDL的锁兼容矩阵实际上包含两部分:活跃锁兼容矩阵,等待锁兼容矩阵。当请求锁时,需要保证两个矩阵对应的值都兼容,才能请求锁成功。为什么要设计等待锁兼容矩阵?我理解这里主要是优先保证DDL操作。因为如果DDL操作在等待一个查询操作时,其他查询还源源不断地进入,可能会导致DDL永远也拿不到锁,而实际情况下,DDL操作的重要性往往比查询或DML重要地多。

1. 请求锁兼容性检查:

1) 检查请求锁是否与已经存在的活跃锁冲突,若冲突,则等待;

2) 检查请求锁是否与已经存在的等待锁冲突,若冲突,则等待。

3) 请求锁成功。

2. 释放锁时机:

1) 语句执行结束后,释放STAMENT类型的锁

2) 事务提交时,先后请求COMMIT类型和释放COMMIT类型的锁

3) 事务提交后,释放TRANSACTION类型的锁

三、MDL应用场景分析

MDL是Mysql层面很重要的锁,很多常见问题的源头以及功能实现都依赖于MDL,以下我会举几个常见的问题和功能进行分析。

1. 为什么查询也会被阻塞?

我们在实际运维过程中,一个常见的场景是,接到手机threadrunning飙高告警,登上主机,show processlist看到一大片线程处于“Waiting for table metadata lock”状态,当然其中也包含查询。下面我通过一个简单的例子重新这个场景。

时间点

会话A

会话B

会话C

1

begin

update t3 set c1=1 where id=1;

2

返回

3

alter table t3 add column c3 int;

4

等待

5

select * from t3

6

等待

7

show processlist

返回结果

8

init

show processlist

Waiting for table metadata lock

alter table t3 add column c3 int

Waiting for table metadata lock

select * from t3

从表2可以看到A会话未提交的事务堵住了回话B的DDL语句,而DDL语句进而又堵住了会话C,从第8步来看,会话B和会话C都处于“Waiting for table metadata lock”状态。从表1我们可以看到,会话A的DML操作会请求TABLE- TRANSACTION- MDL_SHARED_WRITE锁,由于没有执行COMMIT,会一直持有;会话B的DDL操作会请求TABLE-TRANSACTION-EXCLUSIVE锁,由于两把锁互斥,等待;会话C的查询操作会请求TABLE- TRANSACTION- MDL_SHARED_READ锁,虽然MDL_SHARED_READ与活跃锁MDL_SHARED_WRITE不冲突,但是与回话B的等待锁EXCLUSIVE冲突,因此也会等待。遇到这种情况,首先要看看是否存在堵住的DDL,如果存在DDL,然后查询是否有大查询或者未提交的事务,这两种情况都会导致DDL堵住,进而影响普通的查询和DML操作。

2. Mysqldump与全局锁

在实际生产环境中,为了容灾和负载均衡,数据库服务一般由一主一备一对实例组成,主库对外提供读写服务,备库提供只读服务,或纯粹为了容灾使用。在这种体系下,通过mysqldump搭建新的实例时,需要获得一个一致性备份集,并且获得对应的位点(拉取主库binlog的依据),通过全量+增量的方式复制一个数据库实例。Mysqldump中为了保证一致性备份和获取对应的位点,需要设置两个关键的参数--master-data=2 和--single-transaction。我们可以通过mysqld的trace功能,跟踪Mysqldump执行的语句。假设我们要备份chuck库,命令如下:

 ./bin/mysqldump -uchuck -pchuck -P4006 –h127.0.0. --databases chuck mysql --master-data= --single-transaction --default-character-set=utf8 > chuck_dump.sql >chuck_dump.log

开启mysqld的trace功能

--debug=d,query,general:O,/kkk/mysqld.trace

通过mysqld.trace,我大概整理了关键的语句,分析和结果如下图所示。可以看到,mysqldump获取增量位点主要是通过FLUSH TABLES WITH READ LOCK语句的两把字典锁来实现(GLOBAL LOCK和COMMIT LOCK)。整个过程持续时间不长(如果语句没有被阻塞),获取位点后,立即将MDL锁释放。第2到第6步即为持有MDL锁的时间,这段时间内无法开启新事务,已有的事务也无法提交,保证位点的正确性。设置隔离级别为RR,则是获取一致性备份的关键,一致性备份的获取源于MVCC,关于MVCC的实现,后续可以单独写一篇文章。第8到第9步为一个表的备份过程, select语句会获取MDL锁(TABLE:TRANSACTION: MDL_SHARED_READ),执行完毕后,通过rollback语句释放MDL锁。因此除了备份的当前表不能做DDL操作;当前表的DML,以及其它表的DDL和DML都不受影响,所以Mysqldump备份过程中,基本不会阻塞线上的其他语句执行。

步骤

关键语句

含义

作用

1

FLUSH /*!40101 LOCAL */ TABLES

关闭打开表

清空查询缓存

2

FLUSH TABLES WITH READ LOCK

上GLOBAL字典锁:

GLOBAL:

MDL_SHARED

COMMIT:

MDL_SHARED

阻塞新事务,以及活跃事务提交。

为获取一致性位点做准备

3

SET SESSION TRANSACTION ISOLATION LEVEL
REPEATABLE READ

设置事务的隔离级别为RR

保证快照读

4

START TRANSACTION /*!40100 WITH CONSISTENT
SNAPSHOT */

开启事务

5

SHOW MASTER STATUS

获取binlog 位点

用来获取主库的增量的位点

6

UNLOCK TABLES

释放

GLOBAL字典锁

允许其它事务更新

7

SAVEPOINT sp

设置保存点

后续可以逐个表

释放MDL

8

SELECT /*!40001 SQL_NO_CACHE */ * FROM
`t1`

获取表t1的数据

TABLE:TRANSACTION

MDL_SHARED_READ

一致性读

9

ROLLBACK TO SAVEPOINT sp

释放:

TABLE:TRANSACTION

MDL_SHARED_READ

10

SELECT /*!40001 SQL_NO_CACHE */ * FROM `t2`

获取表t2的数据

TABLE:TRANSACTION

MDL_SHARED_READ

一致性读

11

ROLLBACK TO SAVEPOINT sp

释放:

TABLE:TRANSACTION

MDL_SHARED_READ

12

……

13

备份完成

参考文章

http://www.percona.com/blog/2010/04/24/how-fast-is-flush-tables-with-read-lock/

http://blogread.cn/it/article/2338?f=hot1

http://imysql.cn/2008_10_24_deep_into_mysqldump_options

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

  1. mysql metadata lock(二)

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

  2. mysql metadata lock(一)

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

  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. 【译】About the Java Technology

    About the Java Technology Java technology is both a programming language and a platform. The Java Pr ...

  2. 【C#进阶系列】14 字符、字符串和文本编码

    本来写了蛮多的,结果因为重启了一下机器导致写的东西都没了. 然后再回想之前写了什么,反而更像是把知识提炼了一番. 关于字符 字符什么的只要记住.net里面都用的Unicode编码就好.字符和数字之间转 ...

  3. Git submodule 特性

    当你习惯了代码的 VCS 后,基本上是离不开的. 作为一个依赖多个子项目组成的项目,要实现直观的代码逻辑结构,可以考虑使用 Git submodule 特性. 当然,如果只是单独的依赖的话,用依赖管理 ...

  4. oracle分组查询实例ORA-00979和ORA-00937错误分析

    select J.ZWJGH,J.CZZXBH,J.JZZT,J.CWNY,J.JZPZH sum(J.FSE)<!-- 聚合函数字段没在分组条件中--> from JZPZXX J &l ...

  5. 使用PDF.JS在线查看PDF

    过程简单粗暴. 第一步:下载源码https://github.com/mozilla/pdf.js 第二步:将源码拷贝进项目中,可以新建一个PDFShow文件夹存放代码 第三步:修改viewer.js ...

  6. mysql与oracle常用函数及数据类型对比

    最近在转一个原来使用oracle,打算改为mysql的系统,有些常用的oracle函数的mysql实现顺便整理了下,主要是系统中涉及到的(其实原来是专门整理过一个详细doc的,只是每次找word麻烦) ...

  7. Atitit.excel导出 功能解决方案 php java C#.net版总集合.doc

    Atitit.excel导出 功能解决方案 php java C#.net版总集合.docx 1.1. Excel的保存格式office2003 office2007/2010格式1 1.2. 类库选 ...

  8. 苹果浏览器和uc浏览器在移动端的坑(日常积累,随时更新)

    先mark 1 .  移动端uc浏览器不兼容css3 calc() 2 .  ie8下a标签没有内容给宽高也不能触发点击跳转 3 . safari输入框加上readOnly="ture&qu ...

  9. 【再探backbone 02】集合-Collection

    前言 昨天我们一起学习了backbone的model,我个人对backbone的熟悉程度提高了,但是也发现一个严重的问题!!! 我平时压根没有用到model这块的东西,事实上我只用到了view,所以昨 ...

  10. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。问题记录

    电脑是win8 64位,安装oracle 11g r2 64位的,谁知道一切装完毕后,打开项目却连不上oracle数据了...首先是pl/sql连不上,装了oracle服务器,应该是不用再装客户端,p ...