例子1:
| trx1 | trx2 |
|---|---|
| begin;select * from test | |
| alter table test add col1 int;(堵塞) | |
| delete from test limit 1;(死锁) |
例子2:
| trx1 | trx2 |
|---|---|
| begin;delete from test limit 1;或者for update语句 | |
| alter table test add col1 int;(堵塞) | |
| delete from test limit 1;(通过) |
MDL LOCK在获取的时候首先会检测是否本事务中曾经获取过同样类型或者更强的MDL LOCK,这个类型包含锁的对象,锁的等级,持续周期等,如果检测通过则不需要进入优先级和兼容矩阵判断,也就是不会判断是否堵塞,而是直接获得一把锁,因此大概的流程为,这个流程不适用于同一个事务,必须要有2个以上交叉的事务:
- 判断本事务获取过同样的MDL LOCK(或者强度更高),如果有就直接获取,不需要下面步骤,强度排行大约为
S SH SR SW SWLP SU SRO SNW SNRW X----------------------------------->弱 强
- 如果没有,则判断优先级矩阵,用于判断是否当前获取的MDL LOCK优先级更高,不会被堵塞中的MDL LOCK堵塞,如果是则走下一步,如果不是则直接堵塞
- 如果优先级矩阵判断通过,也就是不会被堵塞中的MDL LOCK堵塞,则获取的MDL LOCK和本次获取的兼容矩阵进行判断,如果判断兼容则通过,不堵塞。
例子1
trx1 select 语句获取单存的select语句获取的是SR MDL LOCK锁,而trx2的 alter table 语句会在第一阶段上X锁,很明显不兼容因此堵塞,
Request | Granted requests for lock | type | S SH SR(这里) SW SWLP SU SRO SNW SNRW X | ----------+---------------------------------------------+ X | - - - - - - - - - - |
因此alter 语句堵塞,然后trx1的 delete from 语句需要获取的是SW MDL LOCK,因为这个时候trx2的X锁处于等待,因此在判断优先级矩阵的时候如下,
Request | Pending requests for lock | type | S SH SR SW SWLP SU SRO SNW SNRW X(这里) | ----------+--------------------------------------------+ SW | + + + + + + + - - - |
这部分代码如下,
2547 if (!(m_waiting.bitmap() & waiting_incompat_map)) //这里比较就是优先级矩阵,直接返回了false (gdb) n 2601 return can_grant; (gdb) p can_grant $4 = false
因此trx1 堵塞,这样环形等待出现,MDL LOCK报出了死锁。
例子2
这部分trx2和上面一样,但是问题在于trx1 一开头就获取了一个SW锁,这里DML/for update 语句都是SW MDL LOCK,且对象为test表,持续周期为事务。而第二个delete语句也会需要同样的MDL LOCK,因此在校验的第1步就通过直接获取了不需要在判断是否堵塞的问题了。因此这个例子没有产生死锁。
而这种死锁为MDL LOCK死锁不在innodb层而是在mysql层,因此show engine 是看不到的。
| trx1 | trx2 |
|---|---|
| begin;delete from test limit 1;或者for update语句 | |
| alter table test add col1 int;(堵塞) | |
| select * from test;(通过) |
其他
//强度排行判定bool MDL_ticket::has_stronger_or_equal_type(enum_mdl_type type) const{
const MDL_lock::bitmap_t *
granted_incompat_map= m_lock->incompatible_granted_types_bitmap();
return ! (granted_incompat_map[type] & ~(granted_incompat_map[m_type]));} // sw sr
// ! 1111000000 & ~110000000
// ! 11000000 为 flase SR等级比SW低 相反SW比SR高//兼容级矩阵判定bool MDL_ticket::is_incompatible_when_granted(enum_mdl_type type) const{
return (MDL_BIT(m_type) &
m_lock->incompatible_granted_types_bitmap()[type]);}
MDL_EXCLUSIVE//优先级矩阵判定boolMDL_ticket::is_incompatible_when_waiting(enum_mdl_type type) const{
return (MDL_BIT(m_type) &
m_lock->incompatible_waiting_types_bitmap()[type]);}
编辑推荐:
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- rm -rf数据目录,MySQL故障导致大数据平台彻底瘫痪
rm -rf数据目录,MySQL故障导致大数据平台彻底瘫痪
26-03-01 - 架构师必看!现代应用架构发展趋势与数据库选型建议丨TiDB vs MySQL 专题(一)
- 活动中台系统慢 SQL 治理实践
活动中台系统慢 SQL 治理实践
26-03-01 - MySQL 常用快捷方式全解析:提升数据库操作效率
MySQL 常用快捷方式全解析:提升数据库操作效率
26-03-01 - MySQL 30 周年庆!MySQL 8.4 认证免费考!这次是认真的。。。
- MySQL企业版免费开启,强先体验
MySQL企业版免费开启,强先体验
26-03-01 - MySQL大结果集的优化思路
MySQL大结果集的优化思路
26-03-01 - 第37期 MySQL索引下推
第37期 MySQL索引下推
26-03-01 - 一起免费考 MySQL OCP 认证啦
一起免费考 MySQL OCP 认证啦
26-03-01 - 第39期 MySQL给邮箱,身份证类似的字段添加索引的方法
第39期 MySQL给邮箱,身份证类似的字段添加索引的方法
26-03-01
