现象描述

客户在夜间批量执行数据处理时发生了死锁现象,是由不同的会话并发删除数据引起的,这个问题原因是比较简单,但想通过这个案例让大家熟悉如何去排查死锁问题,如何去阅读死锁日志这才是目的。通过模拟用户死锁现象后,死锁日志如下:

1*** (1) TRANSACTION:2TRANSACTION 39474, ACTIVE 58 sec starting index read3mysql tables in use 1, locked 14LOCK WAIT 3 lock struct(s), heap size 1200, 4 row lock(s), undo log entries 35MySQL thread id 9, OS thread handle 123145525800960, query id 77 localhost root updating6DELETE FROM t1 WHERE id = 47*** (1) WAITING FOR THIS LOCK TO BE GRANTED:8RECORD LOCKS space id 114 page no 4 n bits 80 index PRIMARY of table `dhy`.`t1` trx id 39474 lock_mode X locks rec but not gap waiting9Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
10 0: len 4; hex 00000004; asc     ;;
11 1: len 6; hex 000000009a33; asc      3;;
12 2: len 7; hex 02000001471399; asc     G  ;;
13 3: len 2; hex 6464; asc dd;;
14
15*** (2) TRANSACTION:
16TRANSACTION 39475, ACTIVE 46 sec starting index read
17mysql tables in use 1, locked 1
183 lock struct(s), heap size 1200, 4 row lock(s), undo log entries 3
19MySQL thread id 10, OS thread handle 123145526104064, query id 78 localhost root updating
20DELETE FROM t1 WHERE id = 3
21*** (2) HOLDS THE LOCK(S):
22RECORD LOCKS space id 114 page no 4 n bits 80 index PRIMARY of table `dhy`.`t1` trx id 39475 lock_mode X locks rec but not gap
23Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
24 0: len 4; hex 00000004; asc     ;;
25 1: len 6; hex 000000009a33; asc      3;;
26 2: len 7; hex 02000001471399; asc     G  ;;
27 3: len 2; hex 6464; asc dd;;
28
29Record lock, heap no 6 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
30 0: len 4; hex 00000005; asc     ;;
31 1: len 6; hex 000000009a33; asc      3;;
32 2: len 7; hex 02000001471375; asc     G u;;
33 3: len 2; hex 6565; asc ee;;
34
35Record lock, heap no 7 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
36 0: len 4; hex 00000006; asc     ;;
37 1: len 6; hex 000000009a33; asc      3;;
38 2: len 7; hex 02000001471351; asc     G Q;;
39 3: len 2; hex 6666; asc ff;;
40
41*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
42RECORD LOCKS space id 114 page no 4 n bits 80 index PRIMARY of table `dhy`.`t1` trx id 39475 lock_mode X locks rec but not gap waiting
43Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
44 0: len 4; hex 00000003; asc     ;;
45 1: len 6; hex 000000009a32; asc      2;;
46 2: len 7; hex 01000001462e1f; asc     F. ;;
47 3: len 2; hex 6363; asc cc;;
48
49*** WE ROLL BACK TRANSACTION (2)

如何阅读死锁日志

要排查死锁问题我们就要学会如何查看死锁日志,但MySQL死锁日志看起来并不是很直观需要我们一步一步耐心分析。 
我们将上面的死锁日志拆分阅读,我们可以得出以下信息:

  • 两个事务的事务ID
    TRANSACTION 39474
    TRANSACTION 39475

  • 事务39474在执行delete语句是发生了锁等待

1DELETE FROM t1 WHERE id = 4
2*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
3RECORD LOCKS space id 114 page no 4 n bits 80 index PRIMARY of table `dhy`.`t1` trx id 39474 lock_mode X locks rec but not gap waiting
4Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
5 0: len 4; hex 00000004; asc     ;; //聚集索引的值
6 1: len 6; hex 000000009a33; asc      3;; //事务ID
7 2: len 7; hex 02000001471399; asc     G  ;; //undo 记录
8 3: len 2; hex 6464; asc dd;; //非主键字段的值

通过以上信息可以得出事务39474执行delete语句时,锁等待发生在申请ID=4这条记录上的X锁“lock_mode X locks rec but not gap waiting”

  • 事务39475持有锁的信息

1*** (2) HOLDS THE LOCK(S):2RECORD LOCKS space id 114 page no 4 n bits 80 index PRIMARY of table `dhy`.`t1` trx id 39475 lock_mode X locks rec but not gap3Record lock, heap no 5 PHYSICAL RECORD: n_fields 4; compact format; info bits 324 0: len 4; hex 00000004; asc     ;;5 1: len 6; hex 000000009a33; asc      3;;6 2: len 7; hex 02000001471399; asc     G  ;;7 3: len 2; hex 6464; asc dd;;89Record lock, heap no 6 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
10 0: len 4; hex 00000005; asc     ;;
11 1: len 6; hex 000000009a33; asc      3;;
12 2: len 7; hex 02000001471375; asc     G u;;
13 3: len 2; hex 6565; asc ee;;
14
15Record lock, heap no 7 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
16 0: len 4; hex 00000006; asc     ;;
17 1: len 6; hex 000000009a33; asc      3;;
18 2: len 7; hex 02000001471351; asc     G Q;;
19 3: len 2; hex 6666; asc ff;;

事务39475持有在ID=4,5,6上X锁

  • 事务39475同样在执行delete语句时发生了所等待

1*** (2) TRANSACTION:2TRANSACTION 39475, ACTIVE 46 sec starting index read3mysql tables in use 1, locked 143 lock struct(s), heap size 1200, 4 row lock(s), undo log entries 35MySQL thread id 10, OS thread handle 123145526104064, query id 78 localhost root updating6DELETE FROM t1 WHERE id = 378*** (2) WAITING FOR THIS LOCK TO BE GRANTED:9RECORD LOCKS space id 114 page no 4 n bits 80 index PRIMARY of table `dhy`.`t1` trx id 39475 lock_mode X locks rec but not gap waiting
10Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
11 0: len 4; hex 00000003; asc     ;;
12 1: len 6; hex 000000009a32; asc      2;;
13 2: len 7; hex 01000001462e1f; asc     F. ;;
14 3: len 2; hex 6363; asc cc;;

申请ID=3上的X锁时发生了所等待,执行的语句是:DELETE FROM t1 WHERE id = 3,那么可以得出39474在id=3上持有了X锁,但是在死锁日志中并没有显示出事务39474持有锁的信息
那么这两个事务加锁的顺序应是:
1. 事务39474持有了id=3上的X锁
2. 事务39475持有了id=4上的X锁
3. 事务39474申请id=4上X锁时发生了锁等待执行的语句是:DELETE FROM t1 WHERE id = 4
4. 事务39475申请id=3上X锁时触发了死锁,因为此时双方都在申请对方持有的锁不能进行下去了。

  • 事务2被回滚

1*** WE ROLL BACK TRANSACTION (2)
  • 事务39475持有ID = 4, 5, 6上的X锁是由哪个语句引起的,无法直观从死锁日志里看出。可以通过打开general日志或者binlog或者业务代码来查看整个事务逻辑

实验步骤及表结构

搭建可按实验步骤自己模拟测试,表结构及数据如下:

1CREATE TABLE t1 (id int unsigned NOT NULL PRIMARY KEY, c1
2varchar(10));
3INSERT INTO t1 VALUES (1, 'aa'), (2, 'bb'), (3, 'cc'), (4, 'dd'), (5, 'ee'), (6, 'ff');

操作步骤如表所示:

Session1 Session2
START TRANSACTION;
DELETE FROM t1 WHERE id = 1;
START TRANSACTION;
DELETE FROM t1 WHERE id = 6;
DELETE FROM t1 WHERE id = 2;
DELETE FROM t1 WHERE id = 5;
DELETE FROM t1 WHERE id = 3;
DELETE FROM t1 WHERE id = 4;
DELETE FROM t1 WHERE id = 4;
DELETE FROM t1 WHERE id = 3;
//发生死锁

总结

这个案例根本原因是两个会话同时删除数据时,没有控制好删除的顺序造成了死锁,这就需要我们在做应用开发时对数据库操作一定要注意操作数据的前后关系、是否有数据依赖、会话之间是否会操作相同的数据。
通过这个案例我们也了解到了应如何去阅读和分析死锁日志。


《深入浅出MGR》视频课程

戳此小程序即可直达B站

https://www.bilibili.com/medialist/play/1363850082?business=space_collection&business_id=343928&desc=0



文章推荐:

  • MySQL内存为什么不断增高,怎么让它释放

  • MySQL 存储过程运行的内存管理

  • 无损半同步复制下,主从切换后数据一致吗?

  • 数据中间件如何与MySQL数据同步?

  • MySQL 8.0.30,一个值得上车MGR的版本

  • RC隔离级别下,死锁案例分析

  • 浅析MySQL死锁检测

  • MySQL内存管理机制浅析


想看更多技术好文,点个“在看”吧!

如何阅读MySQL死锁日志相关推荐

  1. mysql死锁日志阅读

    前言 在开发中,我们经常会遇到死锁问题,我们会查看数据库的死锁日志来查看死锁出现的原因,但是死锁日志如果不会阅读的话,可能就导致我们难以进行问题的排查 环境介绍 1.数据库场景 MySQL 5.6 引 ...

  2. mysql 死锁日志_Mysql死锁以及死锁日志分析

    死锁的概念 死锁:死锁一般是事务相互等待对方资源,***形成环路造成的. 对于死锁,数据库处理方法:牺牲一个连接,保证另外一个连接成功执行. 发生死锁会返回ERROR:1213 错误提示,大部分的死锁 ...

  3. MySQL死锁日志的查看和分析

    目录 一,关于MySQL的死锁 二,人造一个死锁的场景 三,查看最近一次死锁的日志 四,死锁日志的内容 1,事务1信息 2,事务1持有的锁 3,事务1正在等待的锁 4,事务2信息 5,事务2正在持有的 ...

  4. java mysql死锁_记一次线上mysql死锁分析(一)

    记录一次比较诡异的mysql死锁日志.系统运行几个月来,就在前几天发生了一次死锁,而且就只发生了一次死锁,整个排查过程耗时将近一天,最后感谢我们的DBA大神和老大一起分析找到原因. 诊断死锁 借助于我 ...

  5. 在线分析mysql死锁详解_记一次线上mysql死锁分析(一)

    记录一次比较诡异的mysql死锁日志.系统运行几个月来,就在前几天发生了一次死锁,而且就只发生了一次死锁,整个排查过程耗时将近一天,最后感谢我们的DBA大神和老大一起分析找到原因. 诊断死锁 借助于我 ...

  6. 记录一次mysql死锁

    一,死锁发现 项目中有一个接口包含更新操作1,后面发现更新失败,通过查看应用程序日志,发现发生了死锁 sql 1 如下 1.最初版本根据id为条件,更新(plan_start_time 二级索引) u ...

  7. MySQL如何阅读死锁日志

    转载地址 http://blog.itpub.net/22664653/viewspace-2145133/ 我在这个文章的基础上进行了排版,添加了一些标题,让可读性更好 一 前言 欲善其事必先利其器 ...

  8. MySQL Innodb表导致死锁日志情况分析与归纳

    案例描述 在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下: (1)insert into back ...

  9. 查看mysql数据库的死锁日志_【MySQL】mysql死锁以及死锁日志分析

    1.死锁的概念 死锁:死锁一般是事务相互等待对方资源,最后形成环路造成的. 对于死锁,数据库处理方法:牺牲一个连接,保证另外一个连接成功执行. 发生死锁会返回ERROR:1213 错误提示,大部分的死 ...

最新文章

  1. scala入门之代码补全
  2. 计算机二级怎么更改报名密码忘记了怎么办,中考报名系统密码忘了怎么办
  3. Elasticsearch 5
  4. python爬取音乐并保存_python3 实现爬取TOP500的音乐信息并存储到mongoDB数据库中
  5. java源程序加密解决方案(基于Classloader解密)
  6. JSTL的错误“attribute test does not accept any expressions”解决方法
  7. iPhone清理喇叭灰尘_厉害了,iPhone 专用的网购商品历史最低价查询工具
  8. amazon 设计 4 vending machine
  9. asp.net JavaScriptSerializer实现序列化和反序列化
  10. 2018 OpenInfra Days China 大咖来袭——开源,我们是认真的
  11. matlab 简单低通滤波器,简单低通滤波器设计及matlab仿真.doc
  12. Jupyter Notebook打开时报错的问题解决办法
  13. win10易升计算机丢失,微软Windows 10易升
  14. WPS Office 2019 For Linux 设置显示语言
  15. 社交电商 社群电商 源码下载
  16. 酷比魔方iplay20_酷比魔方iPlay20Pro配置怎么样?iPlay20Pro处理器性能全面评测
  17. python列表功能默写_python 1 默写用递归实现无限极分类 2 默写用树实现无限极分类...
  18. tagul添加中文字体——最简单的方法
  19. Python 学习入门(1)—— PyDev
  20. 客户需要生成中文拼音代码,分享PHP生成代码

热门文章

  1. 第一次亲密接触J2ME游戏
  2. vue数组更新不渲染页面
  3. HTML5期末大作业:化妆品购物商城网站设计——电商类化妆品购物商城(1页) HTML+CSS+JavaScript 关于电商类的HTML网页设计-----化妆品
  4. Java——MySQL数据库编程练习
  5. Android开发中EditText:一、属性详解
  6. C语言extern关键字用法和理解
  7. 寸拳:从心理到身体的训练线路
  8. 计算机制作贺卡教案,初中信息技术《美化Word文档贺卡制作》教案
  9. 【前端】HTML锚点跳转实现
  10. 《FCOS:Fully Convolutional One-Stage Object Detection》论文笔记