后台-插件-广告管理-首页/栏目/内容广告位一(PC) |
后台-插件-广告管理-首页/栏目/内容广告位一(手机) |
在线上进行DDL操作时,相对于其可能带来的系统负载,其实,我们最担心的还是MDL其可能导致的阻塞问题。
一旦DDL操作因获取不到MDL被阻塞,后续其它针对该表的其它操作都会被阻塞。典型如下,如阻塞稍久的话,我们会看到Threads_running飙升,CPU告警。
mysql> show processlist; +----+-----------------+-----------+-----------+---------+------+---------------------------------+------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-----------------+-----------+-----------+---------+------+---------------------------------+------------------------------------+ | 4 | event_scheduler | localhost | NULL | Daemon | 122 | Waiting alt="MySQL表结构变更,不可不知的Metadata Lock" src="https:///d/file/20240124/4997b735c22d5890c7c8f81f8f4a8a3a.png" />为了提高数据库的并发度,MDL被细分为了11种类型。
-
MDL_INTENTION_EXCLUSIVE
-
MDL_SHARED
-
MDL_SHARED_HIGH_PRIO
-
MDL_SHARED_READ
-
MDL_SHARED_WRITE
-
MDL_SHARED_WRITE_LOW_PRIO
-
MDL_SHARED_UPGRADABLE
-
MDL_SHARED_READ_ONLY
-
MDL_SHARED_NO_WRITE
-
MDL_SHARED_NO_READ_WRITE
-
MDL_EXCLUSIVE
常用的有MDL_SHARED_READ,MDL_SHARE D_WRITE及MDL_EXCLUSIVE,其分别用于SELECT操作,DML操作及DDL操作。其它类型的对应操作可参考源码sql/mdl.h。
对于MDL_EXCLUSIVE,官方的解释是,
/* An exclusive metadata lock. A connection holding this lock can modify both table's metadata and data. No other type of metadata lock can be granted while this lock is held. To be used for CREATE/DROP/RENAME TABLE statements and for execution of certain phases of other DDL statements. */
简而言之,MDL_EXCLUSIVE是独占锁,在其持有期间是不允许其它类型的MDL被授予,自然也包括SELECT和DML操作。
这也就是为什么DDL操作被阻塞时,后续其它操作也会被阻塞。
关于MDL的补充
1. MDL的最大等待时间由lock_wait_timeout参数决定,其默认值为31536000(365天)。在使用工具进行DDL操作时,这个值就不太合理。事实上,pt-online-schema-change和gh-ost对其就进行了相应的调整,其中,前者60s,后者3s。
2. 如果一个SQL语法上有效,但执行时报错,如,列名不存在,其同样会获取MDL锁,直到事务结束才释放。