MySQL笔记-死锁原理与分析及InnoDB中如何减少死锁

根据InnoDB的加锁规则(Record Lock、Gap Lock、meta data lock)可以写出不会发生死锁的SQL语句,也能定位出产生死锁的原因。

 

死锁产生的原因:

产生回路:两个或两个以上的事务在执行过程中,分别持有一把锁,然后再加一把锁(AB-BA)产生死锁。

加锁顺序不一致:两个或两个以上的事务并发执行(同一时刻),因争夺资源而造成的一种互相等待,产生死锁。

 

如下时序图为产生环路:

update操作会参数排他锁。

这里session1把id为1的行加了锁,session2,把ID为2的行加了锁,随后,session1拿id为2的数据,而session2拿id为1的数据,这样就产生了死锁。

下面用mysql来演示下:

表如下:

create table t1( id int not null default 0, name varchar(10), primary key(id) )engine=InnoDB;

查看下:

select * from t1;

这样有产生了死锁:

mysql有解锁机制,这里可以看到产生了Deadlock。然后将其释放了,这样session1就运行成功了!

使用

show engine innodb status \G

可以查看锁相关的信息;

 

在latest detected deadlock。如看到update t1 est name = 'ddddd' where id = 2这个地方产生了死锁。

innodb_print_all_deadlocks开启后可以将死锁信息添加到error.log里面

show variables like '%dead%';

目前是OFF状态。

 

第二种情况产生死锁是在同一时刻。如下时序图:

这里如果session1成功将检索到数据和session2的数据一样,但是顺序不同,就会参数死锁。

如session1获得的数据:

session2检索的数据:

其实就变成了和第一种差不多的形式。

下面来说明下InnoDB中如何减少死锁:

1. 自动死锁检测,优先回滚小事务;

2. 超时设置(参数innodb_lock_wait_timeout);

3. 尽快提交事务,小事务不容易发生死锁;

4. 加for update,lock in share mode读锁时,最好降低事务隔离级别,例如使用RC(读已提交),降低死锁发生概率

5. 事务中涉及多个表,或多行时,每个事务操作顺序要保持一致,最好用存储过程/函数固化;

6. 通过索引等方式优化SQL效率,降低死锁发生概率(减少扫描/锁范围,降低概率;)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值