[TOC]

> 除了我们经常熟知的共享锁和排他锁外,MySQL数据库还有一种锁叫元数据锁,主要为了保证元数据的一致性,用于处理不同线程操作同一数据对象的同步与互斥问题。

# 一、元数据

所谓元数据,就是表示数据的数据,这些数据五花八门,总之,只要不是我们存储到数据库里的数据记录,大多都可以理解为元数据。

描述数据库的任何数据,作为数据库内容的对立面的都是元数据。因此,列名、数据库名、用户名、版本名以及从`SHOW`语句得到的结果中的大部分字符串是元数据。还包括`INFORMATION_SCHEMA`数据库中的表中的内容,因为定义的那些表存储关于数据库对象的信息。

# 二、元数据锁MDL

`metadata lock`是一种为了保证元数据的一致性,用于处理不同线程操作同一数据对象的同步与互斥问题的锁。

MDL锁是为了解决一个有名的[bug989](https://bugs.mysql.com/bug.php?id=989),所以在5.5.3版本引入了MDL锁。5.1对于元数据的保护是语句级别的,5.5对于Metadata的保护是事务级别的。所谓语句级别,即语句执行完成后,无论事务是否提交或回滚,其表结构可以被其他会话更新;而事务级别则是在事务结束后才释放MDL。引入MDL锁主要是为了解决两个问题:

- 事务隔离问题:比如在可重复隔离级别下,会话A在2次查询期间,会话B对表结构做了修改,两次查询结果就会不一致,无法满足可重复读的要求。

- 数据复制问题:比如会话A执行了多条`update`语句期间,另外一个会话B做了`update`并且先提交,就会导致slave在重做时,先重做`alter`,再重做`update`时就会出现复制错误的现象。

DDL操作与MDL锁

- Metadata Lock 机制是为了保证数据一致性存在的,当先后有多个事务对同一个表操作的时候,并且后一个事务在前一个事务结束前就开始了,这时对表的DDL操作就会阻塞,等待获取DDL锁,直到所有的事务都结束才进行DDL操作。

- 自动提交模式下,单语句就是一个事务,执行完了,事务也就结束了。

- Online DDL是指在`alter table`进行的时候,插入/修改/删除数据的sql语句不会`Waiting for table metadata lock`,在5.6以后的版本有支持。一旦alter table TableA的操作停滞在`Waiting for table metadata lock`的状态,后续对TableA的任何操作(包括读)都无法进行,也会在Opening tables的阶段进入`Waiting for table metadata lock `的队列。

# 三、MDL锁的三种场景

在`alter table`时会发生如下三种场景。

## 1、场景一

- 会话 A 对 booboo 表执行读操作`select *,sleep(60) from booboo;`,正在进行未提交事务。

- 会话 B 对 booboo 表执行在线DDL操作`alter table booboo add q4 int default 0;`。

- 会话 C 对 booboo 表执行隐式读操作`select *,sleep(60) from booboo;`进行等待。

- 会话 D 对 booboo 表执行显示读操作`begin;select * from booboo;`也会进行等待。

通过`show full processlist`可以看到会话 A 对booboo表上正在进行的操作,此时会话 B 的`alter table`语句无法获取到metadata 独占锁,会进行等待,会话 C 和会话 D 都会进行等待,且能从 processlist 表中看到对booboo表的操作。会话A提交事务后或`kill`之后,会话C事务结束,会话D `select`语句执行成功,D事务提交则会话B可执行,否则进入场景2。

- 解决方法

第一种情况,`show full processlist; `定位到长时间未提交的事务kill即可。

## 2、场景二

场景一中回话 D 如果忘记最后的`commit;`, 通过`show processlist`是看不到booboo上有任何操作,但实际上存在有未提交的事务,可以使用`select * from information_schema.innodb_trx`查看到。在事务没有完成之前,booboo的锁不会释放,`alter table`同样获取不到metadata的独占锁,所以会话D要么提交事务、要么回滚、要么被kill,则会话B中的Alter可继续执行。

- 解决方法

如果`show processlist`找不到事务的话,执行 `select * from information_schema.innodb_trx`查找事务,找到线程id,kill掉。

## 3、场景三

如果一个SQL语法上有效,但执行时报错,如,列名不存在,其同样会获取MDL锁,直到事务结束才释放。

在场景一中,如果回话 D 在`select`一个不存在的列名,回话 D 也会获取MDL锁,会话B的`alter`语句同样需要等待。解决方法依然是找到会话线程id,kill掉。

# 四、`lock_wait_timeout`设置

MDL的最大等待时间由`lock_wait_timeout`参数决定, `set lock_wait_timeout = 50;` 来设置值,在使用工具进行DDL操作时,这个值就不太合理。事实上,pt-online-schema-change和gh-ost对其就进行了相应的调整,其中,前者60s,后者3s。

mysql MDL锁如何解决_MySQL元数据锁MDL相关推荐

  1. mysql MDL锁如何解决_MYSQL METADATA LOCK(MDL LOCK)MDL锁问题分析

    一.前言 MYSQL中MDL锁一直是一个比较让人比较头疼的问题,我们谈起锁一般更加倾向于INNODB下层的gap lock.next key lock.row lock等,因为它很好理解,也很好观察, ...

  2. mysql MDL锁如何解决_Mysql 中的MDL

    首先简单了解一下 mysql 的 sql 类型: 1.数据定义语言 DDL:Create.Drop.Alter 操作.用于定义库和表结构的. 2.数据查询语言 DQL:select.用于查询数据的. ...

  3. mysql 数据库表被锁住了_mysql数据库锁的产生原因及解决办法

    数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性 ...

  4. mysql行锁表怎么办_mysql - 表锁,行锁

    MyISAM存储引擎:开销小,加锁快,无死锁.锁定粒度大,并发度低,容易发生锁冲突.   不支持事务.            采用表锁 (操作时对操作的表上锁) 基本不用了 innoDB存储引擎:开销 ...

  5. mysql 查看锁表日志_MYSQL 表锁情况查看

    查看锁表情况 mysql> show status like 'Table%'; +----------+--–+ | Variable_name | Value | +----------+- ...

  6. mysql数据锁的类型_MySQL数据库锁类型

    锁概念: 当高并发访问同一个资源时,可能会导致数据不一致,需要一种机制将用户访问数据的顺序进行规范化,以保证数据库数据的一致性.锁就是其中的一种机制. 一个栗子 :以买火车票为例,火车票可面向广大消费 ...

  7. 怎么重置blockinput的锁_AppleID被锁如何解决 AppleID被锁激活方法介绍【图文】

    AppleID被锁怎么办,AppleID被锁激活教程,商家有时候为了省事,会让众多新iPhone用户使用同一个AppleID,但是有时候AppleID会被锁,该怎么办呢?小编今天就告诉大家解决方法. ...

  8. mysql 执行计划 改变_数据量增加导致mysql执行计划改变解决_MySQL

    bitsCN.com 数据量增加导致mysql执行计划改变解决 收到运维同学电话,mysql服务器连接数满了,登录服务器查看,确实满了,好吧,首先增加连接数到2500,暂时提供对外服务.连接继续升高, ...

  9. mysql数据库老是被锁怎么解决_Mysql数据库全局锁是如何引起的,如何解决?

    2019-01-08 回答 乐观锁与悲观锁不同的是,它是一种逻辑上的锁,而不需要数据库提供锁机制来支持 当数据很重要,回滚或重试一次需要很大的开销时,需要保证操作的acid性质,此时应该采用悲观锁 而 ...

最新文章

  1. MyBatis-Plus,搭配 Spring Boot 使用,一篇就够了
  2. 运行c++代码的软件_C语言入门干货:多种系统的C环境设置和简易代码运行
  3. java搭建maven项目_Eclipse使用maven创建Java Web项目完整示例
  4. MFC中使用控制台窗口输入输出
  5. Mysql定时执行任务实现方法
  6. Linux iptables用法与NAT
  7. Sticks UVA - 307(切木棍 线性区间dp,线性dp,区间思想。)
  8. python入门之正则表达式
  9. 53.NFS 服务器
  10. sketchup 255个su常用插件)_[插件课堂] SU.KIT发布了v2020,完美支持SketchUp 2020
  11. httpclient架构原理介绍 连接池详解
  12. Spring中bean的生命周期
  13. 正则表达式实现中文的大写字符
  14. 在线log计算机,log换算(log计算器在线)
  15. 嵌入式与物联网的关系还是挺复杂的,去同存异分析一波
  16. Attention Is All You Need
  17. BMZCTF:insomniteaser_2019_l33t_hoster
  18. 【linux】循序渐进学运维-基础篇-文件的软硬链接
  19. Ubuntu20.04 conda安出错,成功解决:solving environment:failed with initial frozen solve.Retrying with flexibl
  20. 页面水印 原生js 兼容ie8浏览器

热门文章

  1. 【OpenCV 4开发详解】图像上绘制几何图形
  2. 安徽池州贵池中学老师经典语录,我喷了
  3. linux设置ulimit值永久生效
  4. 链接详解--多目标文件的链接
  5. leetcode 5 :Longest Palindromic Substring 找出最长回文子串
  6. 大型网站技术架构(3):WEB 前端性能优化
  7. ssh,FTP到远程服务器时,显示自定义的警告信息
  8. oracle job使用详解及job不运行的检查方法
  9. converter 冷迁
  10. vmware无法打开ubuntu解决办法