mysql出现死锁的原因及解决方案

  本文主要给大家介绍mysql出现死锁的原因及解决方案,文章内容都是笔者用心摘选和编辑的,具有一定的针对性、对大家的参考意义还是比较大的、下面跟笔者一起了解下mysql出现死锁的原因及解决方案吧。
    <李> mysql都有什么锁李

mysql有三种锁的级别:页级、表级,行级,内存级(锁)。

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间,会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

算法:

下一键锁锁,同时锁住记录(数据),并且锁住记录前面

的差距差距锁不锁记录,仅仅记录前面的差距

Recordlock锁(锁数据,不锁Gap)

所以其实Next-KeyLocks=差距锁+ Recordlock锁

    <李>什么情况下会造成死锁李

所谓死锁僵局是指两个或两个以上的进程在执行过程中,
因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等竺的进程称为死锁进程。
表级锁不会产生死锁,所以解决死锁主要还是针对于最常用的InnoDB。

死锁的关键在于:两个(或以上)的会话加锁的顺序不一致。

那么对应的解决死锁问题的关键就是:让不同的会话加锁有次序

4、下面就简单来重现一下死锁:

死锁重现:
事务:
root@test 16:01>选择connection_id ();
+ - - - - - - - - - - - - - - - - - - +
| connection_id () |
+ - - - - - - - - - - - - - - - - - - +
|,,,,,47274 |
+ - - - - - - - - - - - - - - - - - - +
1行组(0.01秒)

root@test 16:02>设置自动提交=0;
查询好,0行影响(0.00秒)

root@test 16:02> select *从t id=1更新;
+——+
| | id
+——+
|, 1 |
+——+
1行组(0.00秒)

root@test 16:02> select *从t id=2更新;
错误1213(40001):死锁发现当试图让锁;试着重新启动事务
root@test 16:03>

事务B:
root@test 16:02>选择connection_id ();
+ - - - - - - - - - - - - - - - - - - +
| connection_id () |
+ - - - - - - - - - - - - - - - - - - +
|,,,,,47272 |
+ - - - - - - - - - - - - - - - - - - +
1行组(0.00秒)

root@test 16:02>设置自动提交=0;
查询好,0行影响(0.00秒)

root@test 16:02> select *从t id=2更新;
+——+
| | id
+——+
|, 2 |
+——+
1行组(0.00秒)

root@test 16:03> select *从t id=1更新;
+——+
| | id
+——+
|, 1 |
+——+
1行组(5.53秒)

===========================================

死锁信息:

最新检测到死锁

2018-10-19 16:03:14 7 f9612b6d700
(1)事务:
870600年事务,积极11秒开始索引读
使用mysql表1,锁定1
锁等待3锁结构(s), 360年堆大小,2行锁(s)
mysql线程id 47272 0 x7f9612e38700 OS线程处理,查询id 1112421 127.0.0.1根统计
选择,从t id=1更新
* *(1)等待这个锁被授予:
记录锁空间id 330页3 n位72指数主要表测试。t trx id 870600 lock_mode X锁rec但不是差距等
(2)事务:
870599年事务,积极22秒开始索引读
使用mysql表1,锁定1
3锁结构(s), 360年堆大小,2行锁(s)
mysql线程id 47274 0 x7f9612b6d700 OS线程处理,查询id 1112422 127.0.0.1根统计
select * t id=2的更新
(2)持有的锁(s):
记录锁空间id 330页3 n位72指数主要表测试。t trx id 870599 lock_mode X锁rec但不是差距
(2)等待这个锁被授予:
记录锁空间id 330页3 n位72指数主要表测试。t trx id 870599 lock_mode X锁rec但不是差距等
* * *我们回滚事务(2)

5分析:
1,这上面是显示是事务产生死锁的sql并打印出相应所持和等待的锁
2,上面的信息并没有输出事务死锁之前的sql,所以可以直接堆出两个事务执行的sql使他们相互持有了对方等待的锁
3,造成死锁是必然的,慢的sql和不合理的业务的逻辑是造成死锁过多的主要原因

重要的事情说三遍:优化sql,优化业务,优化逻辑

看完以上关于mysql出现死锁的原因及解决方案,很多读者朋友肯定多少有一定的了解,如需获取更多的行业知识信息,可以持续关注我们的行业资讯栏目的。

  

mysql出现死锁的原因及解决方案