MySQL死锁记录
今天线上环境偶现了一个 Deadlock found when trying to get lock; try restarting transaction 的报错,排查了一下,下面先模拟一下操作再说下排查流程
- 模拟操作
- 数据库脚本准备
CREATE TABLE t (i INT) ENGINE = INNODB;INSERT INTO t (i) VALUES(1);
- A 客户端执行:
START TRANSACTION;SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
- B 客户端执行:
START TRANSACTION;DELETE FROM t WHERE i = 1;
- 然后A客户端再执行:
UPDATE t SET i = 2WHERE i = 1;
这时B客户端就会报死锁的错误
- 排查流程
- 命令行登录MySql服务端
mysql -h 127.0.0.1 -P 3306 -u root -p
- 查看死锁日志
show engine innodb status G;
- 找到日志里的 LATEST DETECTED DEADLOCK 下面的内容
- 从日志里我们能看到 A 客户端(截图里的 *** (2) TRANSACTION: ) 首先获得了一个 S锁(共享锁),然后 B 客户端要获取 X锁(互斥锁,对应上面的 delete 操作),然后 A 客户端也想要获取 X锁(对应上面的 update 操作),造成了相互等待,形成了死锁。最后的结果是 A 客户端操作执行成功,B 客户端回滚了。
- 解决方法
我在线上遇到的问题是因为表字段没加索引,其中一条SQL造成了全表加锁,在加了索引之后还在观察中。
官方的说法也是要让事务尽量更新行数小、执行快,减小锁的时间。
以上是 MySQL死锁记录 的全部内容, 来源链接: utcz.com/z/512228.html