当前位置:网站首页>Mysql 死锁和死锁的解决方案
Mysql 死锁和死锁的解决方案
2022-08-05 07:02:00 【三3三】
最近在研究Mysql底层原理,研究到了死锁,感觉挺有意思,在这里和大家分享一下
前置知识:需要了解锁的种类,如表锁、行锁;行锁又分为记录锁、间隙锁、临键锁等等;什么情况下会加表锁,什么情况下会加行锁,什么情况下会加临键锁,什么情况锁会升级等等。。。网上讲解很多,这里就不单独讲述了
一 表死锁
产生原因:
用户A访问表A(锁住了表A),然后又访问表B;另一个用户B访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。
用户A–>A表(表锁)–>B表(表锁)
用户B–>B表(表锁)–>A表(表锁)
解决方案:
这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量按照相同的顺序进行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理, 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。
二 行死锁
产生原因1:
如果在事务中执行了一条没有索引条件的查询,引发全表扫描,把行级锁上升为全表记录锁定(等价于表级锁),多个这样的事务执行后,就很容易产生死锁和阻塞,最终应用系统会越来越慢,发生阻塞或死锁。
解决方案1:
SQL语句中不要使用太复杂的关联多表的查询;使用explain“执行计划"对SQL语句进行分析,对于有全表扫描和全表锁定的SQL语句,建立相应的索引进行优化。
产生原因2:
两个事务分别想拿到对方持有的锁,互相等待,于是产生死锁。
例如:
事务A
Begin;
Select * from t1 where id = 1 for update;
Update t1 set name = ‘aa’ where id = 5;
事务B
Begin;
Delete from t1 where id = 5;
Delete from t1 where id = 1;
事务A获取到了id=1的记录锁,执行update的时候,需要拿到id=5的锁;同时事务B拿到了id=5的记录锁,又需要拿到id=1的锁,因此两个事务同时进入无线阻塞状态,这就产生了死锁。
产生原因3:
每个事务即使只有一个SQL,但是有些情况还是会发生死锁
事务A,从name索引出发 , 读到的[hdc, 1], [hdc, 6]均满足条件, 不仅会加name索引上的记录X锁, 而且会加聚簇索引上的记录X锁, 加锁顺序为先[1,hdc,100], 后[6,hdc,10]
事务B,从pubtime索引出发,[10,6],[100,1]均满足过滤条件,同样也会加聚簇索引上的记录X锁,加锁顺序为[6,hdc,10],后[1,hdc,100]。
但是加锁时发现事务B跟事务A的加锁顺序正好相反,两个事务恰好都持有了第一把锁,请求加第二把锁,死锁就发生了。
如下图所示:
解决方案2、3:
上面的原因2和原因3出现死锁的原因, 都是对索引加锁顺序的不一致导致的,所以如果可以,尽量以相同的顺序来访问索引记录和表。在程序以批量方式处理数据的时候,如果事先对数据排序,保证每个线程按固定的顺序来处理记录,也可以大大降低出现死锁的可能;
三 死锁总结
- 对索引加锁顺序的不一致很可能会导致死锁, 所以如果可以, 尽量以相同的顺序来访问索引记录和表. 在程序以批量方式处理数据的时候, 如果事先对数据排序, 保证每个线程按固定的顺序来处理记录, 也可以大大降低出现死锁的可能.
- 间隙锁往往是程序中导致死锁的真凶, 由于默认情况下 MySQL 的隔离级别是 RR,所以如果能确定幻读和不可重复读对应用的影响不大, 可以考虑将隔离级别改成 RC, 可以避免 Gap 锁导致的死锁.
- 为表添加合理的索引, 如果不走索引将会为表的每一行记录加锁, 死锁的概率就会大大增大.
- 避免大事务, 尽量将大事务拆成多个小事务来处理. 因为大事务占用资源多, 耗时长, 与其他事务冲突的概率也会变高.
- 避免在同一时间点运行多个对同一表进行读写的脚本, 特别注意加锁且操作数据量比较大的语句.
- 设置锁等待超时参数:innodb_lock_wait_timeout,在并发访问比较高的情况下,如果大量事务因无法立即获得所需的锁而挂起,会占用大量计算机资源,造成严重性能问题,甚至拖跨数据库。我们通过设置合适的锁等待超时阈值,可以避免这种情况发生。
边栏推荐
猜你喜欢
RNote108---Display the running progress of the R program
Flink Learning 11: Flink Program Parallelism
二叉树进阶复习1
AI + video technology helps to ensure campus security, how to build a campus intelligent security platform?
FPGA parsing B code----serial 4
typescript63-索引签名类型
2022起重机司机(限桥式起重机)考试题库及模拟考试
Modeling of the MAYA ship
IO process thread -> communication between processes -> day7
Hash these knowledge you should also know
随机推荐
4520. 质数
2022.8.2 模拟赛
typescript60-泛型工具类型(readonly)
FPGA parsing B code----serial 4
软件测试必问面试题(附答案和解析)
Promise (3) async/await
在anaconda Promat界面import torch通过,在jupyter notebook中报错的问题(仅提供思路理解!)
3555. 二叉树
本地能ping通虚拟机,虚拟机ping不通本地
TRACE32——外设寄存器查看与修改
工作3年,回想刚入门和现在的今昔对比,笑谈一下自己的测试生涯
环网冗余式CAN/光纤转换器 CAN总线转光纤转换器中继集线器hub光端机
开启防火墙iptable规则后,系统网络变慢
《基于R语言的自动数据收集》--第3章 XML和JSON
性能提升400倍丨外汇掉期估值计算优化案例
对数据类型而言运算符无效。运算符为 add,类型为 text。
腾讯业务安全岗 IDP 谈话总结
Vulnhub靶机:HA_ NARAK
【JVM调优】Xms和Xmx为什么要保持一致
GAN generates anime avatar Pytorch