- 作者:老汪软件技巧
- 发表时间:2024-09-07 15:05
- 浏览量:
大家可以思考一下,这个执行过程中都会加哪些锁?会发生锁等待吗?会发生死锁吗?
上面执行第3步会锁等待,执行第4步会死锁。
执行如下SQL
SHOW ENGINE INNODB STATUS;
它是MySQL 中一个非常有用的命令,它用于显示 InnoDB 存储引擎的当前状态信息。这个命令对于诊断 InnoDB 存储引擎的问题、监控性能以及理解内部操作非常有帮助。
输出的内容非常多,我们只关注锁信息就行,找到LATEST DETECTED DEADLOCK 最近一次死锁信息如下:
2.3.3 死锁日志分析
现在让我们来分析这个死锁日志,我只会分析我们需要的信息。
2.3.3.1 事务A23087信息
*** (1) "TRANSACTION":<br/>
TRANSACTION 23087, ACTIVE 22 sec inserting<br/>
mysql tables in use 1, locked 1<br/>
LOCK WAIT 3 lock struct(s), heap size 1128, 2 row lock(s), undo log entries 1<br/>
MySQL thread id 9, OS thread handle 123145459134464, query id 1039 localhost 127.0.0.1 root update<br/>
INSERT INTO checkout_detail ( id, recycle_order_id, confirm_recycle_time, contrast_type, remark )VALUES( 30, 30, '2024-07-15 "19":56:01', 1, "插入回收单30" )<br/>
0. 事务状态 事务ID:23087 操作:正在进行插入(INSERT)操作。
锁等待情况 锁结构数量:3个锁结构,这表明MySQL为该事务准备了多个锁来管理对数据的访问。 行锁数量:2个行锁,说明事务试图在checkout_detail表中的两行数据上设置锁。事务阻塞 LOCK WAIT:这表明事务正在等待其他事务释放锁。在当前情况下,它正在等待能够插入或更新它试图操作的两行数据。2.3.3.2 事务23087持有锁
*** (1) HOLDS THE "LOCK(S)":
RECORD LOCKS space id 4 page no 5 n bits 72 index uniq_idx_recycle_order_id_contrast_type of table `my_database`.`checkout_detail` trx id 23087 lock_mode X
Record lock, heap no 1 PHYSICAL "RECORD": n_fields 1; compact format; info bits 0
"0": len 8; hex 73757072656d756d; asc supremum;;
事务23087持有的锁是一个针对uniq_idx_recycle_order_id_contrast_type索引的X(排他)锁,但它实际上锁定的是索引中的“supremum”伪记录。这通常意味着事务并没有锁定任何具体的、存在的数据行,而是锁定了一个表示索引末尾的虚拟记录。
2.3.3.3 事务23087等待锁
*** (1) WAITING FOR THIS LOCK TO BE "GRANTED":
RECORD LOCKS space id 4 page no 5 n bits 72 index uniq_idx_recycle_order_id_contrast_type of table `my_database`.`checkout_detail` trx id 23087 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL "RECORD": n_fields 1; compact format; info bits 0
"0": len 8; hex 73757072656d756d; asc supremum;;
事务23087正在等待一个插入意向锁(lock_mode X insert intention waiting)被授予
2.3.3.4 事务23088信息
** (2) "TRANSACTION":
TRANSACTION 23088, ACTIVE 14 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1128, 2 row lock(s), undo log entries 1
MySQL thread id 10, OS thread handle 123145460199424, query id 1043 localhost 127.0.0.1 root update
INSERT INTO checkout_detail ( id, recycle_order_id, confirm_recycle_time, contrast_type, remark )VALUES( 40, 40, '2024-07-15 "19":56:01', 1, "插入回收单40" )
0. 事务状态 事务ID:23088 操作:正在进行插入(INSERT)操作。
锁等待情况 锁结构数量:3个锁结构,这表明MySQL为该事务准备了多个锁来管理对数据的访问。 行锁数量:2个行锁,说明事务试图在checkout_detail表中的两行数据上设置锁。事务阻塞 LOCK WAIT:这表明事务正在等待其他事务释放锁。在当前情况下,它正在等待能够插入或更新它试图操作的两行数据。2.3.3.5 事务23088持有锁
*** (2) HOLDS THE "LOCK(S)":
RECORD LOCKS space id 4 page no 5 n bits 72 index uniq_idx_recycle_order_id_contrast_type of table `my_database`.`checkout_detail` trx id 23088 lock_mode X
Record lock, heap no 1 PHYSICAL "RECORD": n_fields 1; compact format; info bits 0
"0": len 8; hex 73757072656d756d; asc supremum;;
事务23088持有的锁是一个针对uniq_idx_recycle_order_id_contrast_type索引的X(排他)锁,但它实际上锁定的是索引中的“supremum”伪记录。这通常意味着事务并没有锁定任何具体的、存在的数据行,而是锁定了一个表示索引末尾的虚拟记录。
2.3.3.6 事务23088等待锁
*** (2) WAITING FOR THIS LOCK TO BE "GRANTED":
RECORD LOCKS space id 4 page no 5 n bits 72 index uniq_idx_recycle_order_id_contrast_type of table `my_database`.`checkout_detail` trx id 23088 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL "RECORD": n_fields 1; compact format; info bits 0
"0": len 8; hex 73757072656d756d; asc supremum;;
事务23088正在等待一个插入意向锁(lock_mode X insert intention waiting)被授予
3 分析原因
参考MySQL的。
间隙锁(Gap Locks)是一种特殊的锁机制,用于锁定索引记录之间的间隙,或者第一个索引记录之前的间隙以及最后一个索引记录之后的间隙。这种锁的主要目的是防止其他事务在这些间隙中插入新的记录,从而维护数据的一致性和隔离性。
插入意向锁(Insert Intention Locks) 是InnoDB存储引擎在插入操作前设置的一种间隙锁(Gap Locks)。这种锁的目的是在多个事务尝试向同一个索引间隙中插入不同位置的数据时,能够并行执行而不需要相互等待。
可以得到索引如下加锁示意图
锁总是锁定索引记录。如果要锁定的是最后一条记录之后的区间,防止有人在这个区间插入数据,那么mysql就会锁定隐藏的最大记录
4 解决方法
1、查看死锁日志时,先看一下发生死锁的事务等待获取锁的语句, 都有哪些语句发生死锁。
2、根据死锁语句,找到相关到业务代码(如果有日志,直接根据日志找到业务代码也行)。
3、根据业务代码执行流程,来分析死锁发生过程。(注意分析数据存在,数据不存在时的加锁区别)
发现了问题原因,那么解决方案就很简单了。在这个场景下是:先查询数据是否存在,如果数据存在则更新,如果数据不存在再插入。
5 总结
关于作者
黄培祖 采货侠JAVA开发工程师
> 转转研发中心及业界小伙伴们的技术学习交流平台,定期分享一线的实战经验及业界前沿的技术话题。
> 关注公众号「转转技术」(综合性)、「大转转FE」(专注于FE)、「转转QA」(专注于QA),更多干货实践,欢迎交流分享~