首先,这里不考虑innodb行锁,仅仅考虑MDL LOCK和DML/select 语句。我们知道到了8.0.28(包含)以后,记录慢查询的标准有变化,主要依赖的实际执行时间,而不是以前去掉了锁的时间(包含MDL LOCK和行锁)作为判定标准,具体参考, https://www.jianshu.com/p/27547eb97d6a
以前通常通过lock_time来判断是否可能出现过innodb行锁堵塞和MDL LOCK堵塞,但是后来发现在8.0.28(包含)以后lock_time记录的时间变化了,通常并不包含innodb表的MDL LOCK时间,可以做测试如下,首先设置参数, set global long_query_time = 0,位了记录全部的满查询。
使用如下步骤,我们观察最后selet 语句的lock_time时间是否包含了MDL LOCK时间
| 步骤 | session1 | session2 | session3 |
|---|---|---|---|
| 1. | begin;select * from t1 | ||
| 2. | alter table t1 add ic int; | ||
| 3. | select * from t1; (我们主要观察本语句lock time记录时间的不同) | ||
| 4. | commit; |
其中第2步开始 session2和session3 因为mdl lock的原因不能获取到锁,直到第4步commit解锁。
8.0.28及之后的记录
# Time: 2024-10-08T17:40:48.426038+08:00# User@Host: root[root] @ localhost [] Id: 29# Query_time: 13.729913 Lock_time: 0.000019 Rows_sent: 2 Rows_examined: 2SET timestamp=1728380434;select * from t1;
注意这里的lock_time,几乎没有什么值,而这两个语句很明显的是等待在MDL LOCK下面,而lock_time几乎为0, 因此在8.0.28及之后即便Lock_time为0不能说明语句没有遇到MDL LOCK。
8.0.28及之前的记录,这里使用8.0.23
注意这里一定要将long_query_time 设置为0,否则如果主要等待在MDL LOCK上,去掉这部分时间后可能实际执行时间已经很短了,因此如果不设置long_query_time 为0不会记录任何慢查询。
# Time: 2024-10-08T18:02:47.417947+08:00# User@Host: root[root] @ localhost [] Id: 19# Query_time: 16.397964 Lock_time: 16.396849 Rows_sent: 1 Rows_examined: 1SET timestamp=1728381751;select * from t1;
这里我们能看到Lock_time实际上还是至少是包含了mdl lock的时间的。
大体原因
对于一般的DML和SELCET语句来讲,8.0.28之前的版本记录的lock _time的时候语句当跑到mysql_lock_tables函数的时候计算一次时间,这个时间实际上包含了MDL LOCK的时间,但是到了8.0.28(包含)以后这里发生了一些变化,仅仅记录了mysql_lock_tables函数里面消耗的时间,可以在函数找到如下几句,
ulonglong lock_start_usec = my_micro_time(); //仅仅是这一段 记录到了lock timeulonglong lock_end_usec = my_micro_time(); //结束thd->inc_lock_usec(lock_end_usec - lock_start_usec);//计算
但是innodb表的MDL LOCK堵塞并不包含在这个函数中,因此8.0.28及过后的MDL LOCK堵塞就不会记录了。 但是myisam的表锁是包含在其中,当我们使用myisam 测试表锁的时候会发现表锁的时间记录在里面,如下是8.0.36的测试,
myisam表记录的慢查询如下,
# Time: 2024-10-08T18:27:27.772193+08:00# User@Host: root[root] @ localhost [] Id: 28# Query_time: 67.663484 Lock_time: 67.636786 Rows_sent: 0 Rows_examined: 4SET timestamp=1728383180;delete from testmyisam;
可以看到即便是8036,myisam的表锁也包含在Lock_time中。
总结
编辑推荐:
- 慢查询中关于MDL LOCK记录的变化03-01
- 主从半同步降级异步分析03-01
- 一个古老的死锁BUG终于修复了03-01
- mysql面试03-01
- 如何让SQL速度飞起来 入门YashanDB优化器03-01
- 数智化转型 | 星环科技Defensor 助力某银行数据分类分级03-01
- 刚刚!MySQL创新版9.2.0发布,学爆它!03-01
- 【SQLAOT】一个用来辅助SQL优化工作的工具03-01
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- 慢查询中关于MDL LOCK记录的变化
慢查询中关于MDL LOCK记录的变化
26-03-01 - 主从半同步降级异步分析
主从半同步降级异步分析
26-03-01 - mysql面试
mysql面试
26-03-01 - 如何让SQL速度飞起来 入门YashanDB优化器
如何让SQL速度飞起来 入门YashanDB优化器
26-03-01 - 数智化转型 | 星环科技Defensor 助力某银行数据分类分级
数智化转型 | 星环科技Defensor 助力某银行数据分类分级
26-03-01 - 刚刚!MySQL创新版9.2.0发布,学爆它!
刚刚!MySQL创新版9.2.0发布,学爆它!
26-03-01 - 【SQLAOT】一个用来辅助SQL优化工作的工具
【SQLAOT】一个用来辅助SQL优化工作的工具
26-03-01 - 开发一个集婚恋相亲、交友、多人语音互动于一体的APP系统
开发一个集婚恋相亲、交友、多人语音互动于一体的APP系统
26-03-01 - 第26期 MySQL区分大小写
第26期 MySQL区分大小写
26-03-01 - 数据库数据恢复——MySQL数据库Delete命令误删除数据如何恢复数据?
