关于mysql:MDL-为什么DDL不锁表而是阻塞了所有该表的SQL

4次阅读

共计 966 个字符,预计需要花费 3 分钟才能阅读完成。

基础知识

SQL

Structured Query Language
数据操纵和数据定义等多种性能的数据库语言,可分为以下四类

  • DDL
    Data Definition Language
    数据定义语言 create drop alter truncate 等
  • DML
    Data Manipulation Language
    数据操作语言 insert update delete 等
  • DQL
    Data Query Language
    数据查询语言 select
  • DCL
    Data Control Language
    数据管制语言 grant revoke 等

MDL

meta data lock,直译为元数据锁

  • 从 MySQL 5.5 开始引入
  • MDL 加锁是零碎自动控制
  • MDL 读读共享,读写互斥,写写互斥

对表 DML & DQL 时,零碎会主动加 MDL 读锁;
对更 DDL 时,会加 MDL 写锁;
其意义在于,增删改查只操作表内的数据,不影响表构造,故只须要读取元数据信息(即表构造信息),此时增删改查能够并行,只是不能批改表构造;
而加写锁时,只有获取锁的线程能够读写元数据(即批改表构造信息),其余线程不能批改构造也不能执行增删改查操作;

MDL 可能引起的问题

承上可知,执行 DDL 时会阻塞该表的增删查改操作,如果表数据量过大,或者表的读写十分频繁时,可能会引发性能问题,DDL 持续时间过长,就会长工夫阻塞后续操作,导致大量线程期待锁的开释,导致程序解体

Online DDL

MySQL 5.6 引入了 Online DDL,来解决上述 MDL 可能引发的问题,Online DDL 具体执行过程如下

  1. 获取 MDL 写锁(即阻塞该表的增删查改操作)
  2. 将 MDL 写锁降级成 MDL 读锁(让该表的增删查改操作失常执行)
  3. 执行真正的 DDL 操作(即批改表构造),此过程十分耗时,但此时持有的是 MDL 读锁,并不会阻塞增删改查操作(即做到并行)
  4. 实现 DDL 操作后,将 MDL 读锁降级为 MDL 写锁
  5. 开释 MDL 锁

为什么 DDL 不锁表,而是阻塞了所有该表的 SQL

由上述信息可知,执行 DDL 时,并非锁住整个表,而是在第 1 步与第 4 步中的 MDL 写锁阻塞了该表的增删查改操作

仍可能引发的问题

Waiting for table metadata lock
由上述信息可知,执行 DDL 须要获取 MDL 写锁,若有一个执行工夫很长的事务,始终不开释 MDL 读锁,则 DDL 就须要长时间期待,具体场景能够自行查阅官网文档以及其余博客,此处不再赘述

正文完
 0