基础知识

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就须要长时间期待,具体场景能够自行查阅官网文档以及其余博客,此处不再赘述