MySQL笔记-死锁原理与分析及InnoDB中如何减少死锁
发布日期:2021-06-30 10:43:04 浏览次数:3 分类:技术文章

本文共 1103 字,大约阅读时间需要 3 分钟。

根据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效率,降低死锁发生概率(减少扫描/锁范围,降低概率;)

转载地址:https://it1995.blog.csdn.net/article/details/105937207 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:MySQL笔记-MDL锁(metadata lock)
下一篇:MySQL笔记-InnoDB中Record Lock与Gap Lock

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月13日 10时35分52秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章