前言

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. 微软Dynamics 使用葡萄城的Wijmo 5提供移动端用户界面选择

    近日,全球最大的控件提供商葡萄城公司宣布: 葡萄城近日与微软公司达成合作,将Wijmo 产品线的HTML5和JaveScript 控件融合到微软Dynamics CRMOnline 2016版中. 随 ...

  2. MySQL远程登录设置

    可以在一台机器上访问另一台机器的MySQL,但是需要一些设置. 进入MySQL后,输入以下命令: GRANT ALL PRIVILEGES ON *.* TO 'tigase'@'%' IDENTIF ...

  3. luogg_java学习_04_数组

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 数组 数组是多个相同类型数据的组合 //1.定义数组 ...

  4. Java分布式开发

    分布式概念的引入是基于性能的提升,应用的可靠性而提出的.所谓Java分布式,即是在使用Java语言进行企业级应用开发的过程中,采用分布式技术解决业务逻辑的高并发.高可用性的一些架构设计方案. 1. R ...

  5. 十大Intellij IDEA快捷键

    转载:http://blog.csdn.net/dc_726/article/details/42784275 Intellij IDEA中有很多快捷键让人爱不释手,stackoverflow上也有一 ...

  6. 项目中应用eventbus解决的问题

    在项目开发过程中,往往有些功能表面看起来简单,但实际开发的结果非常复杂,仔细分析下原因发现很多都是因为附加了许多的额外功能. 真的简单吗? 比如我们对一个电商平台的商品数据做修改的功能来讲,其实非常简 ...

  7. SQL SERVER常用定义查询

    https://msdn.microsoft.com/en-us/library/ms175081.aspx

  8. CSDN数据库被爆 统计CSDN用户都喜欢哪些密码

    今天有黑客在网上公开了知名网站CSDN的用户数据库,这是一次严重的暴库泄密事件,涉及到的账户总量高达600万个.有人写了一个小程序,统计了这次公布的 6428632 个 CSDN 哪些密码出镜率较高? ...

  9. 20个免费的 AngularJS 资源和开发教程

    曾经,jQuery 无疑是最受欢迎的开源的 JavaScript 库,如今它有了很多的竞争对手,像 AngularJS.React.KnockoutJS 等等.在这里,我想重点关注一下 Angular ...

  10. heX——基于 HTML5 和 Node.JS 开发桌面应用

    heX 是网易有道团队的一个开源项目,允许你采用前端技术(HTML,CSS,JavaScript)开发桌面应用软件的跨平台解决方案.heX 是你开发桌面应用的一种新的选择,意在解决传统桌面应用开发中繁 ...