MySQL死锁

1. 死锁的产生

        两个以上的会话在抢占资源过程中,产生互相等待的情况。

        死锁建立在锁等待的基础上,session A 获取id=1的写锁,session B 获取id=2的写锁,此时由于索引不同,顾不会发生锁等待现象;当session A 尝试获取id=2的写锁时,由于id=2已经被session A获取,此时产生锁等待,由于 sessionA 和 session B 同时都在锁等待状态,产生了等待对方释放锁,故会产生死锁。

示例:

  • session A 执行语句,获取id=1的写锁权限:
BEGIN;
UPDATE `order` SET `year`='2021' WHERE id=1;
  • session B 执行语句,获取id=2的写锁权限:
BEGIN;
UPDATE `order` SET `year`='2022' WHERE id=2; 
  • session A 执行语句,尝试获取id=2的写锁权限,进入锁等待状态:
UPDATE `order` SET `year`='2022' WHERE id=2;
  • session B 执行语句,尝试获取id=1的写锁权限,进入锁等待状态:
update  `order` set `year`= '2022' where id = '1';

当 B 进入 锁等待后就直接报死锁异常

Deadlock found when trying to get lock; try restarting transaction

2. 查看死锁

可使用 show engine innodb status 查看死锁

......
*** (1) TRANSACTION: // 事物A
TRANSACTION 253507, ACTIVE 474 sec starting index read
mysql tables in use 1, locked 1 // 已经使用一个锁
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 17001, OS thread handle 139824777217792, query id 2191731 ......
root updating
update `order` set `year`= '2022' where id = '2'//执行得语句
*** (1) WAITING FOR THIS LOCK TO BE GRANTED: // 等待锁释放获取锁
RECORD LOCKS space id 65 page no 3 n bits 80 index PRIMARY of table `zszxz`.`order` trx id 253507 lock_mode X locks rec but not gap waiting
.....*** (2) TRANSACTION: // 事物 B
TRANSACTION 253508, ACTIVE 425 sec starting index read
mysql tables in use 1, locked 1 // 已经使用一个锁
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 17002, OS thread handle 139824778569472, query id 2191735 ......
root updating
update  `order` set `year`= '2022' where id = '1'//执行得语句
*** (2) HOLDS THE LOCK(S): //持有锁
RECORD LOCKS space id 65 page no 3 n bits 80 index PRIMARY of table `zszxz`.`order` trx id 253508 lock_mode X locks rec but not gap
......*** (2) WAITING FOR THIS LOCK TO BE GRANTED: // 等待锁释放获取锁
RECORD LOCKS space id 65 page no 3 n bits 80 index PRIMARY of table `zszxz`.`order` trx id 253508 lock_mode X locks rec but not gap waiting
......

字母代表锁的类型如下:

  • 共享锁(S)
  • 排他锁(X)
  • 意向共享(IS)
  • 意向排他(IX)
  • gap lock(GK) 间隙锁,锁定一个范围,不包括当前记录本身
  • RECORD LOCKS 代表记录锁

可以看出上面的语句(1)代表 事务A,MySQL线程ID17001,(2)代表 事务B,MySQL线程ID17002,事务A与B都在等待对方释放锁,产生了死锁。

知识点

  • 查看表锁:show status like 'table%';

解决死锁

  • 查找到死锁线程,杀死MySQL死锁的线程(kill命令)
  • 如果事务未提交,直接回滚事务

3. 如何避免死锁

  • 在死锁容易产生的表使用表锁不会产生死锁;
  • 避免交叉使用相同的锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值