iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL中怎么排查死锁
  • 329
分享到

MySQL中怎么排查死锁

2024-04-02 19:04:59 329人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关Mysql中怎么排查死锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。死锁起因先介绍一下数据库和表情况,因为涉及到公司内部真是的

这篇文章将为大家详细讲解有关Mysql中怎么排查死,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

死锁起因

先介绍一下数据库和表情况,因为涉及到公司内部真是的数据,所以以下都做了模拟,不会影响具体的分析。

我们采用的是 5.5 版本的 mysql 数据库事务隔离级别是默认的 RR(Repeatable-Read),采用 innodb 引擎。假设存在 test 表:

CREATE TABLE `test` (  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  `a` int(11) unsigned DEFAULT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `a` (`a`) ) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;

表的结构很简单,一个主键 id,另一个***索引 a。表里的数据如下:

mysql> select * from test;  +----+------+  | id | a    |  +----+------+  |  1 |    1 |  |  2 |    2 |  |  4 |    4 |  +----+------+  3 rows in set (0.00 sec)

出现死锁的操作如下:

步骤事务 1事务 2
1 begin
2 delete from test where a = 2;
3begin 
4delete from test where a = 2; (事务 1 卡住) 
5提示出现死锁:ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transactioninsert into test (id, a) values (10, 2);


然后我们可以通过 SHOW ENGINE INNODB STATUS; 来查看死锁日志

------------------------  LATEST DETECTED DEADLOCK  ------------------------  170219 13:31:31  *** (1) TRANSACTION:  TRANSACTION 2A8BD, ACTIVE 11 sec starting index read  mysql tables in use 1, locked 1  LOCK WaiT 2 lock struct(s), heap size 376, 1 row lock(s)  MySQL thread id 448218, OS thread handle 0x2abe5fb5d700, query id 18923238 renjun.fanGCloud.net 121.41.41.92 root updating  delete from test where a = 2  *** (1) WAITING FOR THIS LOCK TO BE GRANTED:  RECORD LOCKS space id 0 page no 923 n bits 80 index `a` of table `oauthdemo`.`test` trx id 2A8BD lock_mode X waiting  Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact fORMat; info bits 32  0: len 4; hex 00000002; asc     ;;  1: len 4; hex 00000002; asc     ;;  *** (2) TRANSACTION:  TRANSACTION 2A8BC, ACTIVE 18 sec inserting  mysql tables in use 1, locked 1  4 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 2  MySQL thread id 448217, OS thread handle 0x2abe5fd65700, query id 18923239 renjun.fangcloud.net 121.41.41.92 root update  insert into test (id,a) values (10,2)  *** (2) HOLDS THE LOCK(S):  RECORD LOCKS space id 0 page no 923 n bits 80 index `a` of table `oauthdemo`.`test` trx id 2A8BC lock_mode X locks rec but not gap  Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32  0: len 4; hex 00000002; asc     ;;  1: len 4; hex 00000002; asc     ;;  *** (2) WAITING FOR THIS LOCK TO BE GRANTED:  RECORD LOCKS space id 0 page no 923 n bits 80 index `a` of table `oauthdemo`.`test` trx id 2A8BC lock mode S waiting  Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32  0: len 4; hex 00000002; asc     ;;  1: len 4; hex 00000002; asc     ;;  *** WE ROLL BACK TRANSACTION (1)

分析

阅读死锁日志

遇到死锁,***步就是阅读死锁日志。死锁日志通常分为两部分,上半部分说明了事务 1 在等待什么锁:

170219 13:31:31  *** (1) TRANSACTION:  TRANSACTION 2A8BD, ACTIVE 11 sec starting index read  mysql tables in use 1, locked 1  LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)  MySQL thread id 448218, OS thread handle 0x2abe5fb5d700, query id 18923238 renjun.fangcloud.net 121.41.41.92 root updating  delete from test where a = 2  *** (1) WAITING FOR THIS LOCK TO BE GRANTED:  RECORD LOCKS space id 0 page no 923 n bits 80 index `a` of table `oauthdemo`.`test` trx id 2A8BD lock_mode X waiting  Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32  0: len 4; hex 00000002; asc     ;;  1: len 4; hex 00000002; asc     ;;

从日志里我们可以看到事务 1 当前正在执行 delete from test where a = 2,该条语句正在申请索引 a 的 X 锁,所以提示 lock_mode X waiting。

然后日志的下半部分说明了事务 2 当前持有的锁以及等待的锁: 

*** (2) TRANSACTION:  TRANSACTION 2A8BC, ACTIVE 18 sec inserting  mysql tables in use 1, locked 1  4 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 2  MySQL thread id 448217, OS thread handle 0x2abe5fd65700, query id 18923239 renjun.fangcloud.net 121.41.41.92 root update  insert into test (id,a) values (10,2)  *** (2) HOLDS THE LOCK(S):  RECORD LOCKS space id 0 page no 923 n bits 80 index `a` of table `oauthdemo`.`test` trx id 2A8BC lock_mode X locks rec but not gap  Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32  0: len 4; hex 00000002; asc     ;;  1: len 4; hex 00000002; asc     ;;  *** (2) WAITING FOR THIS LOCK TO BE GRANTED:  RECORD LOCKS space id 0 page no 923 n bits 80 index `a` of table `oauthdemo`.`test` trx id 2A8BC lock mode S waiting  Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32  0: len 4; hex 00000002; asc     ;;  1: len 4; hex 00000002; asc     ;;

从日志的 HOLDS THE LOCKS(S) 块中我们可以看到事务 2 持有索引 a 的 X 锁,并且是记录锁(Record Lock)。该锁是通过事务 2 在步骤 2 执行的 delete 语句申请的。由于是 RR 隔离模式下的基于***索引的等值查询(Where a = 2),所以会申请一个记录锁,而非 next-key 锁。

从日志的 WAITING FOR THIS LOCK TO BE GRANTED 块中我们可以看到事务 2 正在申请 S 锁,也就是共享锁。该锁是 insert into test (id,a) values (10,2) 语句申请的。insert 语句在普通情况下是会申请排他锁,也就是 X 锁,但是这里出现了 S 锁。这是因为 a 字段是一个***索引,所以 insert 语句会在插入前进行一次 duplicate key 的检查,为了使这次检查成功,需要申请 S 锁防止其他事务对 a 字段进行修改。

那么为什么该 S 锁会失败呢?这是对同一个字段的锁的申请是需要排队的。S 锁前面还有一个未申请成功的 X 锁,所以 S 锁必须等待,所以形成了循环等待,死锁出现了。

通过阅读死锁日志,我们可以清楚地知道两个事务形成了怎样的循环等待,再加以分析,就可以逆向推断出循环等待的成因,也就是死锁形成的原因。

死锁形成流程图

为了让大家更好地理解死锁形成的原因,我们再通过表格的形式阐述死锁形成的流程:

步骤
事务 1事务 2
1 begin
2 delete from test where a = 2; 执行成功,事务 2 占有 a=2 下的 X 锁,类型为记录锁。
3begin 
4delete from test where a = 2; 事务 1 希望申请 a=2 下的 X 锁,但是由于事务 2 已经申请了一把 X 锁,两把 X 锁互斥,所以 X 锁申请进入锁请求队列。 
5出现死锁,事务 1 权重较小,所以被选择回滚(成为牺牲品)。insert into test (id, a) values (10, 2); 由于 a 字段建立了***索引,所以需要申请 S 锁以便检查 duplicate key,由于插入的 a 的值还是 2,所以排在 X 锁后面。但是前面的 X 锁的申请只有在事务 2commit 或者 rollback 之后才能成功,此时形成了循环等待,死锁产生。


拓展

在排查死锁的过程中,有个同事还发现了上述场景会产生另一种死锁,该场景无法通过手工复现,只有高并发场景下才有可能复现。

该死锁对应的日志这里就不贴出了,与上一个死锁的核心差别是事务 2 等待的锁从 S 锁换成了 X 锁,也就是 lock_mode X locks gap before rec insert intention waiting。我们还是通过表格来详细说明该死锁产生的流程:

步骤
事务 1事务 2
1 begin
2 delete from test where a = 2; 执行成功,事务 2 占有 a=2 下的 X 锁,类型为记录锁。
3begin 
4 【insert 第 1 阶段】insert into test (id, a) values (10, 2); 事务 2 申请 S 锁进行 duplicate key 进行检查。检查成功。
5delete from test where a = 2; 事务 1 希望申请 a=2 下的 X 锁,但是由于事务 2 已经申请了一把 X 锁,两把 X 锁互斥,所以 X 锁申请进入锁请求队列。 
6出现死锁,事务 1 权重较小,所以被选择回滚(成为牺牲品)。【insert 第 2 阶段】insert into test (id, a) values (10, 2); 事务 2 开始插入数据,S 锁升级为 X 锁,类型为 insert intention。同理,X 锁进入队列排队,形成循环等待,死锁产生。

关于MySQL中怎么排查死锁就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: MySQL中怎么排查死锁

本文链接: https://www.lsjlt.com/news/57584.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL中怎么排查死锁
    这篇文章将为大家详细讲解有关MySQL中怎么排查死锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。死锁起因先介绍一下数据库和表情况,因为涉及到公司内部真是的...
    99+
    2022-10-18
  • mysql死锁怎么排查及解决
    MySQL死锁是指两个或多个事务互相持有对方需要的资源,同时又等待对方释放资源,导致系统无法继续进行下去的情况。解决MySQL死锁问...
    99+
    2023-09-21
    mysql
  • Java中怎么排查死锁
    这期内容当中小编将会给大家带来有关Java中怎么排查死锁,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。首先,我们构造一个死锁场景。如何构造一个死锁呢很简单,只要让线程1占有对象a的锁后,再去请求对象b的锁...
    99+
    2023-06-15
  • sql server中怎么排查死锁
    sql server中怎么排查死锁,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。死锁的四个必要条件:互斥条件(Mutual exclusi...
    99+
    2022-10-18
  • 如何排查MySQL死锁警告
    本篇内容介绍了“如何排查MySQL死锁警告”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 故障背...
    99+
    2022-10-18
  • Mysql死锁排查实例分析
    这篇文章主要介绍“Mysql死锁排查实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Mysql死锁排查实例分析”文章能帮助大家解决问题。   问题初现  ...
    99+
    2022-10-19
  • MySQL 死锁异常排查和处理
    场景 删除车辆信息同时异步通知查询服务更新 查询服务采用 insert into view 方式增加数据(导致行级锁) 查询服务和删除车辆 争夺车辆表的锁,造成死锁 服务报错日志 2022-...
    99+
    2023-09-28
    mysql java
  • 记一次神奇的Mysql死锁排查
    背景说起Mysql死锁,之前写过一次有关Mysql加锁的基本介绍,对于一些基本的Mysql锁或者死锁都有一个简单的认识,可以看下这篇文章为什么开发人员需要了解分布式锁。有了上面的经验之后,本以为对于死锁都能...
    99+
    2022-10-18
  • java排查死锁示例
    目录死锁示例 死锁产生原因 死锁排查 方案 1:jstack 方案 2:jconsole 方案 3:jvisualvm 方案 4:jmc 总结 死锁(Dead Lock)指的是两个或...
    99+
    2022-11-12
  • 一次神奇的MySQL死锁排查记录
    背景 说起Mysql死锁,之前写过一次有关Mysql加锁的基本介绍,对于一些基本的Mysql锁或者死锁都有一个简单的认识,可以看下这篇文章为什么开发人员需要了解数据库锁。有了上面的经验之后,本以为对于死锁都...
    99+
    2022-10-18
  • sql server怎么排查死锁优化性能
    本篇内容主要讲解“sql server怎么排查死锁优化性能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sql server怎么排查死锁优化性能”吧!一.概述记得以前客户在使...
    99+
    2023-06-29
  • mysql死锁排查及解决的方法是什么
    MySQL死锁是指两个或多个事务相互等待对方持有的资源,导致无法继续执行的情况。为了排查和解决MySQL死锁,可以采取以下方法:1....
    99+
    2023-08-16
    mysql
  • 一次线上MySQL死锁告警原因排查
    项目场景:一次线上MySQL死锁告警原因排查 最近处理了一次线上数据告警,记录一下。 问题描述 同步书架书籍的接口频繁抛出异常,提示数据库出现死锁,异常如下: 本日异常次数:2,异常日志:java.lang.RuntimeExcept...
    99+
    2021-02-11
    一次线上MySQL死锁告警原因排查
  • mysql查询死锁语句怎么写
    这篇“mysql查询死锁语句怎么写”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“mysql...
    99+
    2023-02-16
    mysql
  • sqlserver排查死锁优化性能
    一.概述 记得以前客户在使用软件时,有偶发出现死锁问题,因为发生的时间不确定,不好做问题的重现,当时解决问题有点棘手了。现总结下查看死锁的常用二种方式。 1.1 第一种是图形化监听:...
    99+
    2022-11-13
  • sql server中死锁排查的示例分析
    这篇文章主要介绍sql server中死锁排查的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!死锁的四个必要条件:互斥条件(Mutual exclusion):资源不能被共享...
    99+
    2022-10-18
  • mysql中如何排查并发插入引起的死锁问题
    小编给大家分享一下mysql中如何排查并发插入引起的死锁问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!挂着VPN排查问题,不...
    99+
    2022-10-18
  • MySQL中怎么实现死锁
    这篇文章将为大家详细讲解有关MySQL中怎么实现死锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.了解锁等待与死锁出现锁等待或死锁的原因是访问数据库需要...
    99+
    2022-10-18
  • mysql中怎么解除死锁
    这篇文章主要介绍了mysql中怎么解除死锁,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、第一种:查询是否锁表show OPEN TABLES ...
    99+
    2023-06-15
  • mysql查询为什么会有锁死
    mysql查询为什么会有锁死?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。mysql查询为什么会有锁死死锁就是进程在执行过程中,因争夺资源...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作