MySQL死锁怎么检测和避免

在我们使用锁的时候,有一个问题是需要注意和避免的,我们知道,排它锁有互斥的特性。一个事务或者说一个线程持有锁的时候,会阻止其他的线程获取锁,这个时候会造成阻塞等待,如果循环等待,会有可能造成死锁

这个问题我们需要从几个方面来分析,一个是锁为什么不释放,第二个是被阻塞了怎么办,第三个死锁是怎么发生的,怎么避免。

锁的释放与阻塞

回顾:锁什么时候释放?
事务结束(commit,rollback)﹔
客户端连接断开。

如果一个事务一直未释放锁,其他事务会被阻塞多久?会不会永远等待下去?
如果是,在并发访问比较高的情况下,如果大量事务因无法立即获得所需的锁而挂起,会占用大量计算机资源,造成严重性能问题,甚至拖跨数据库。

线上怕不怕这个错?

[Err] 1205 - Lock wait timeout exceeded; try restarting transaction

MySQL有一个参数来控制获取锁的等待时间,默认是50秒。

show VARIABLES like "innodb_lock_wait_timeout";

对于死锁,是无论等多久都不能获取到锁的,这种情况,也需要等待50秒钟吗?那不是白白浪费了50秒钟的时间吗?

死锁的发生和检测

演示一下,开两个会话:

方便对时间线的提现,这里用图片,有兴趣的可以跟着模仿一下

栗子一:

MySQL死锁怎么检测和避免

栗子二:

MySQL死锁怎么检测和避免

在名列前茅个事务中,检测到了死锁,马上退出了,第二个事务获得了锁,不需要等待50秒:

[Err] 1213 - Deadlock found when trying to get lock; try restarting transaction

为什么可以直接检测到呢?是因为死锁的发生需要满足一定的条件,对于我们程序员来说,有明确的条件,意味着能判定,所以在发生死锁时,InnoDB一般都能通过算法(wait-for graph)自动检测到。

那么死锁需要满足什么条件?死锁的产生条件,因为锁本身是互斥的:

  • (1)同一时刻只能有一个事务持有这把锁;

  • (2)其他的事务需要在这个事务释放锁之后才能获取锁,而不可以强行剥夺;

  • (3)当多个事务形成等待环路的时候,即发生死锁。

理发店有两个总监。一个负责剪头的Tony老师,一个负责洗头的Kelvin老师。Tony老师不能同时给两个人剪头,这个就叫互斥

Tony在给别人在剪头的时候,你不能让他停下来帮你剪头,这个叫不能强行剥夺
如果Tony的客户对Kelvin说:你不帮我洗头我怎么剪头? Kelvin 的客户对Tony说:你不帮我剪头我怎么洗头?这个就叫形成等待环路
实际上,发生死锁的情况非常多,但是都满足以上3个条件。
这个也是表锁是不会发生死锁的原因,因为表锁的资源都是一次性获取的

如果锁一直没有释放,就有可能造成大量阻塞或者发生死锁,造成系统吞吐量下降,这时候就要查看是哪些事务持有了锁。

查看锁信息(日志)

首先,SHow STATUS命令中,包括了一些行锁的信息:

show status like 'innodb_row_lock_%';

MySQL死锁怎么检测和避免

lnnodb_row_lock_current_waits:当前正在等待锁定的数量;
lnnodb_row_lock_time :从系统启动到现在锁定的总时间长度,单位ms;
Innodb_row_lock_time_avg :每次等待所花平均时间;
Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花的时间;
lnnodb_row_lock_waits :从系统启动到现在总共等待的次数。

SHOW命令是一个概要信息。InnoDB还提供了三张表来分析事务与锁的情况:

select * from information_schema.INNODB_TRX; --当前运行的所有事务﹐还有具体的语句

MySQL死锁怎么检测和避免

select* from information_schema.INNODB_LOCKS; --当前出现的锁

MySQL死锁怎么检测和避免

select * from information_schema.INNODB_LOCK_WAITS; --锁等待的对应关系

MySQL死锁怎么检测和避免

更加详细的锁信息,开启标准监控和锁监控:

额外的监控肯定会消耗额外的性能

set GLOBAL innodb_status_output=ON;set GLOBAL innodb_status_output_locks=ON;

通过分析锁日志,找出持有锁的事务之后呢?
如果一个事务长时间持有锁不释放,可以kill事务对应的线程ID,也就是INNODB_TRX表中的trx_mysql_thread_id,例如执行kill 4,kill 7, kill 8。
当然,死锁的问题不能每次都靠kill线程来解决,这是治标不治本的行为。我们应该尽量在应用端,也就是在编码的过程中避免。
有哪些可以避免死锁的方法呢?

死锁的避免

  • 1、在程序中,操作多张表时,尽量以相同的顺序来访问(避免形成等待环路)

  • 2、批量操作单张表数据的时候,先对数据进行排序(避免形成等待环路);

  • 3、申请足够级别的锁,如果要操作数据,就申请排它锁;

  • 4、尽量使用索引访问数据,避免没有where条件的操作,避免锁表;

  • 5、如果可以,大事务化成小事务;

  • 6、使用等值查询而不是范围查询查询数据,命中记录,避免间隙锁对并发的影响。

感谢各位的阅读,以上就是“MySQL死锁怎么检测和避免”的内容了,经过本文的学习后,相信大家对MySQL死锁怎么检测和避免这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

文章标题:MySQL死锁怎么检测和避免,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/24200

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022年9月10日 下午11:42
下一篇 2022年9月10日 下午11:43

相关推荐

  • cad背景如何调成黑色

    cad背景调成黑色的方法: 1、首先打开cad,右键工具栏,打开“选项” 2、接着进入上方“显示”选项卡。 3、然后打开其中的“颜色”设置。 4、随后选中“背景”选项。 5、再将右边的颜色改为“黑” 6、改完后,点击右下角“应用并关闭”即可将背景调成黑色。 “cad背景如何调成黑色”的内容就介绍到这…

    2022年8月30日
    13700
  • windows会声会影x5怎么注册

    会声会影x5注册教程 1、首先我们下载安装会声会影x5。 2、安装完成之后打开。 3、点击“继续”。 4、勾选名列前茅个选项,然后点击“继续”。 5、然后输入购买时的用户名密码就可以了。 6、如果我们目前没有购买,想先试用一下,可以勾选下面的“稍后注册”就可以先行使用体验了。 7、在下次打开时,我们…

    2022年9月15日
    14000
  • thumb文件夹可以删除吗

    thumb指的是系统隐藏缓存文件,可以删除;thumb文件是系统为例提高文件夹在缩略图查看方式下的响应速度而对当前文件夹下的图像文件建立的缓存,可以方便用户对图片进行预览,删除或者禁用都不会对系统造成影响。 本教程操作环境:windows10系统、DELL G3电脑。 thumb是什么文件夹?可以删…

    2022年9月18日
    83500
  • 如何一键接入排查SolarWinds供应链APT攻击

    SolarWinds供应链APT攻击事件被爆出 近日,SolarWinds供应链APT攻击事件引起了业界的关注。SolarWinds官方发布公告称,在SolarWinds Orion Platform的2019.4 HF5到2020.2.1及其相关补丁包的受影响版本中,存在高度复杂后门行为的恶意代码…

    2022年9月15日
    13200
  • idaPro如何分析app解密lua脚本

    通过前面idaPro调试或hook,我们可以获取到xxtea解密key,对于sign我们可以直接打开原文件: 可以看到sign值:byds。所以,我们可以同过xxtea解密工具(可从GitHub上下源码自己编译)试着解密: 以index.luac为例,我们看index.luac解密前后变化: 我们看…

    2022年9月21日
    29100
  • todesk如何听到对方电脑声音

    todesk听到对方电脑声音的方法 1、首先点击电脑开始菜单,点击“运行” 2、输入gpedit.msc后,点击确定 3、打开计算机配置菜单下的管理模板,点击所有设置。 4、找到并双击打开“允许音频和视频播放重定向”选项 5、勾选已启用,点击确定保存设置并重启就可以了。 关于“todesk如何听到对…

    2022年9月26日
    5.3K00
  • Web.config在渗透中的作用是什么

    前言  下面主要介绍web.config文件在渗透中的作用,即可上传一个web.config时的思路,话不多说,开始正题。首先我们来看一下web.config是什么,援引百度百科的介绍:  Web.config文件是一个XML文本文件,它用来储存ASP.NETWeb 应用程序的配置信息,它可以出现在…

    2022年9月24日
    18700
  • SpringBoot断言机制的原理是什么

    JUnit 5 内置的断言可以分成如下几个类别: 1.简单断言 用来对单个值进行简单的验证。如: 方法 说明 assertEquals 判断两个对象或两个原始类型是否相等 assertNotEquals 判断两个对象或两个原始类型是否不相等 assertSame 判断两个对象引用是否指向同一个对象 …

    2022年9月15日
    10900
  • Android动画怎么实现

    1.先看一段动画的代码实现 ObjectAnimator alpha = ObjectAnimator.ofFloat(view, “alpha”, 1, 0,1);alpha.setDuration(500);alpha.start(); 代码很简单,上面三行代码就可以开启一个透明度变化的动画。 …

    2022年8月27日
    14500
  • SQL窗口函数之排名窗口函数怎么使用

    取值窗口函数可以用于返回窗口内指定位置的数据行。常见的取值窗口函数如下: LAG函数可以返回窗口内当前行之前的第N行数据。LEAD函数可以返回窗口内当前行之后的第N行数据。FIRST_VALUE函数可以返回窗口内名列前茅行数据。LAST_VALUE函数可以返回窗口内最后一行数据。NTH_VALUE函…

    2022年9月10日
    18900
联系我们
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部