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

基础知识

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就需要长时间等待,具体场景可以自行查阅官方文档以及其他博客,此处不再赘述

你可能感兴趣的:(mysql)