共计 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 具体执行过程如下
- 获取 MDL 写锁(即阻塞该表的增删查改操作)
- 将 MDL 写锁降级成 MDL 读锁(让该表的增删查改操作失常执行)
- 执行真正的 DDL 操作(即批改表构造),此过程十分耗时,但此时持有的是 MDL 读锁,并不会阻塞增删改查操作(即做到并行)
- 实现 DDL 操作后,将 MDL 读锁降级为 MDL 写锁
- 开释 MDL 锁
为什么 DDL 不锁表,而是阻塞了所有该表的 SQL
由上述信息可知,执行 DDL 时,并非锁住整个表,而是在第 1 步与第 4 步中的 MDL 写锁阻塞了该表的增删查改操作
仍可能引发的问题
Waiting for table metadata lock
由上述信息可知,执行 DDL 须要获取 MDL 写锁,若有一个执行工夫很长的事务,始终不开释 MDL 读锁,则 DDL 就须要长时间期待,具体场景能够自行查阅官网文档以及其余博客,此处不再赘述
正文完