基础知识
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具体执行过程如下
- 获取MDL写锁(即阻塞该表的增删查改操作)
- 将MDL写锁降级成MDL读锁(让该表的增删查改操作正常执行)
- 执行真正的DDL操作(即修改表结构),此过程非常耗时,但此时持有的是MDL读锁,并不会阻塞增删改查操作(即做到并行)
- 完成DDL操作后,将MDL读锁升级为MDL写锁
- 释放MDL锁
为什么DDL不锁表,而是阻塞了所有该表的SQL
由上述信息可知,执行DDL时,并非锁住整个表,而是在第1步与第4步中的MDL写锁阻塞了该表的增删查改操作
仍可能引发的问题
Waiting for table metadata lock
由上述信息可知,执行DDL需要获取MDL写锁,若有一个执行时间很长的事务,一直不释放MDL读锁,则DDL就需要长时间等待,具体场景可以自行查阅官方文档以及其他博客,此处不再赘述
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。