参考文章

《记录一次MySQL死锁的分析与解决过程》

《mysql之show engine innodb status解读》

《把MySQL中的各种锁及其原理都画出来》

写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。

在之前的文章(《mysql运维脚本与个人理解》)中介绍了Mysql运维的几个简单脚本。

但最后的死锁根因分析因为缺少实践经验与分析文章搁置了,这里来补上。

目录

一、行锁的实现

二、show engine innodb status的介绍与使用

1、内容介绍

2. 内容分析

3. 解决办法

一、行锁的实现

在《mysql之事务、锁、隔离级别与MVCC》一文中,介绍了行锁是基于索引的,只有在命中索引时才会出现行锁。但实际上并没有解释清楚行锁是怎么做到精确锁住每一行数据的,也因此带来了一些疑问,比如:2个单列索引,假设事务A通过索引1获取了行锁,既然是加在索引上的锁,那也就意味着,只是锁住了索引1,而索引2上是没有限制的,是否意味着事务2可以通过索引2改动这一行的数据?

要回答这个问题,我们首先回顾下《mysql库中索引的基础概念》中介绍的InnoDB的索引物理结构,二级索引通过主键索引访问数据。

重点来了,行锁实际上也会判断命中的索引是否为主键,如不是,则会在该命中的索引以及主键索引上加锁,如下图所示。因此,开头提到的问题自然是无法修改的,因为最后的最后有主键索引把关。

(图片来源《把MySQL中的各种锁及其原理都画出来》)

二、show engine innodb status的介绍与使用

很多时候我们的死锁出现后立马就会回滚,无法通过报错日志直接定位到异常的sql语句,这里就需要使用mysql为我们提供的分析工具show engine innodb status

1、内容介绍

下面是前几天刚遇到的问题,正好拿来做介绍。

------------------------
LATEST DETECTED DEADLOCK
------------------------
2021-08-18 14:04:16 0x7f29f2ef5700
*** (1) TRANSACTION:
TRANSACTION 14235673, ACTIVE 0 sec starting index read
mysql tables in use 3, locked 3
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 10089425, OS thread handle 139823504013056, query id 157595766 10.75.34.61 dbroot updating
update table1 set aaa='4',bbb='121',ccc='合格',ddd='0',eee='' where bd='6f174b50-8d32' and dw='1e0adeed-3f0d-450a' and tag =1
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14096 page no 57 n bits 272 index bd_index of table `mydatabase`.`table1` trx id 14235673 lock_mode X locks rec but not gap waiting
Record lock, heap no 114 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 30; hex 36663137346235302d386433322d343763362d613062622d633962333238; asc 6f174b50-8d32-47c6-a0bb-c9b328; (total 36 bytes);1: len 30; hex 30636538343031652d653061662d343733362d623031372d626464623663; asc 0ce8401e-e0af-4736-b017-bddb6c; (total 36 bytes);*** (2) TRANSACTION:
TRANSACTION 14235674, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
9 lock struct(s), heap size 1136, 6 row lock(s), undo log entries 2
MySQL thread id 10089424, OS thread handle 139818146158336, query id 157595768 10.75.34.61 dbroot updating
update table1 set aaa='10',bbb='12',ccc='合格',ddd='0',eee='' where bd='6f174b50-8d32' and dw='ffb27cdc-ba40-4e16' and tag =1
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 14096 page no 57 n bits 272 index bd_index of table `mydatabase`.`table1` trx id 14235674 lock_mode X locks rec but not gap
Record lock, heap no 114 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 30; hex 36663137346235302d386433322d343763362d613062622d633962333238; asc 6f174b50-8d32-47c6-a0bb-c9b328; (total 36 bytes);1: len 30; hex 30636538343031652d653061662d343733362d623031372d626464623663; asc 0ce8401e-e0af-4736-b017-bddb6c; (total 36 bytes);*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 14096 page no 57 n bits 272 index bd_index of table `mydatabase`.`table1` trx id 14235674 lock_mode X locks rec but not gap waiting
Record lock, heap no 105 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 30; hex 36663137346235302d386433322d343763362d613062622d633962333238; asc 6f174b50-8d32-47c6-a0bb-c9b328; (total 36 bytes);1: len 30; hex 66396262333533362d356137342d343633352d386335632d323666356537; asc f9bb3536-5a74-4635-8c5c-26f5e7; (total 36 bytes);*** WE ROLL BACK TRANSACTION (1)

TRANSACTION 14235673, ACTIVE 0 sec starting index read   

事务14235673,ACTIVE 0 sec表示事务处于活跃状态0s,starting index read表示正在使用索引读取数据行 

mysql tables in use 3, locked 3

事务1正在使用3个表,且涉及锁的表有3个

LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1

这行表示在等待3把锁,占用内存1136字节,涉及2行记录,如果事务已经锁定了几行数据。

MySQL thread id 10089425, OS thread handle 139823504013056, query id 157595766 10.75.34.61 dbroot updating

该事务的线程ID信息,操作系统句柄信息,连接来源、用户等

update table1 set aaa='4',bbb='121',ccc='合格',ddd='0',eee='' where bd='6f174b50-8d32' and dw='1e0adeed-3f0d-450a' and tag =1

正在等待行锁的sql

*** (1) WAITING FOR THIS LOCK TO BE GRANTED:

*** (2) HOLDS THE LOCK(S):

正在等待的锁、目前保存的锁

RECORD LOCKS space id 14096 page no 57 n bits 272 index bd_index of table `mydatabase`.`table1` trx id 14235673 lock_mode X locks rec but not gap waiting

等待的锁是一个record lock,空间id是14096,页编号为57,大概位置在页的272位处,锁发生在表mydatabase.table1的bd_index 索引上,是一个X锁,但是不是gap lock。 waiting表示正在等待锁

Record lock, heap no 114 PHYSICAL RECORD: n_fields 2; compact format; info bits 0

这行表示record lock的heap no 位置(可以用来对照事务2控制住的锁)

*** WE ROLL BACK TRANSACTION (1)

回滚了事务1

2. 内容分析

通过观察事务1等待的行锁在堆中的位置,与事务2获取到的锁在堆中的位置,确定了事务2手中有事务1想要获取的锁。再来分析涉及到的sql,我们发现产生冲突的是同1条sql,在table1这张表中,bd与dw是一对多的关系(这里假设是1:10),也就导致要获取bd_index(基于bd的单列索引)时,要获取到全部的10个bd上的索引,也就导致产生了争用。

3. 解决办法

问题的原因在于单列索引扫描的范围过大,要获取到全部10个db上的索引,那么我们只要减小获取锁的范围就好了,这里就到了我们的组合索引展示优势的地方了。我们建立bd,dw上的组合索引,这样一来,事务1和事务2中的2条sql都只要获取到自身涉及到的那1条组合索引即可。

create index complex_index on table1(bd,dw);

mysql死锁分析工具show engine innodb status相关推荐

  1. 两个小工具,MySQL死锁分析,新技能又Get!!!

    数据库死锁,是最难调试与追踪的. 场景如下: 同一个表,事务内先插入一条记录,再更新这条记录,并发时会死锁. 并且能够复现. 可以通过什么工具模拟并发事务,查看信息,解决问题呢?这是今天要分享的内容. ...

  2. mysql 打印_故障分析 | MySQL:5.6大事务show engine innodb status故障一例

    作者:高鹏(网名八怪) 文章末尾有他著作的<深入理解 MySQL 主从原理 32 讲>,深入透彻理解 MySQL 主从,GTID 相关技术知识. 本文来源:转载自公众号-老叶茶馆, (作者 ...

  3. mysql innodb monitor_mysql:innodb monitor(show engine innodb status)探秘

    在旧的版本里面是show innodb status命令,新版本后改动了一些:show engine innodb status; 我们最熟悉的,应当就是show innodb status命令,可以 ...

  4. show engine innodb status解读

    show engine innodb status解读 参考 https://www.cnblogs.com/xiaoboluo768/p/5171425.html show engine innod ...

  5. 线上MySQL死锁分析——索引设置不当导致的死锁

    文章目录 1. 背景 2. MySQL InnoDB的锁机制 2.1 MySQL中的锁类型 2.2 行锁的加锁规则 2.3 死锁检测机制 3. 本文案例分析 3.1 分析InnoDB status日志 ...

  6. checkpoint机制,show engine innodb status

    show engine innodb status G 四个参数能反应出来什么 Checkpoint详解 引子 check point是做什么的 作用 Checkpoint所做的事情 checkpoi ...

  7. MYSQL-show engine innodb status

    mysql> show engine innodb status\G; *************************** 1. row ************************** ...

  8. show engine innodb status\G

    mysql> show engine innodb status\G *************************** 1. row *************************** ...

  9. show engine innodb status和innodb锁监控

    目录 innodb monitor概述 innodb monitor的类型 innodb标准监控-Standard InnoDB Monitor innodb锁监控-InnoDB Lock Monit ...

最新文章

  1. Mobileye_EyeQ4功能和性能
  2. 备战 ‘金三银四’ 必备超多软件测试面试题全在这里
  3. Druid连接池一个设置引发的血案
  4. 雷人的调查:荷兰女性的安全意识
  5. 使用snoopy logger记录用户命令
  6. php ci框架中载入css和js文件失败的原因及解决方法
  7. 【拔刀吧少年】之shell函数
  8. 使用IPSec加强系统安全性
  9. SpringBoot2.1.5(23)---SpringBoot 开发WEB应用
  10. PAT乙级 1033 旧键盘打字 (20 分)
  11. 配置Android应用开发环境
  12. linux服务之FTP服务篇
  13. [禅悟人生]先将小事做好再来修禅心
  14. 爆款升级当贝NEW D3X来了,画质亮度远超坚果O1S,性能小钢炮实至名归
  15. dci odbc mysql_人大金仓-
  16. 关于词嵌入(Word Embedding)的一些总结
  17. 大厂项目实战,让你面试被问到项目时不再哑口无言!
  18. Win7系统专业版调整屏幕亮度的详细教程--win7w.com
  19. Vue + 高德地图 + 三维模型
  20. 计算机科学与技术博士论文,计算机科学与技术一级学科博士研究生发表学术论文量化标准.pdf...

热门文章

  1. 最受java程序员欢迎的极佳性能测试工具
  2. 全新IT资源内控安全解决方案
  3. Unity WebGL的Autodesk Interactive渲染问题
  4. 网件路由器虚拟服务器在哪里,网件路由器怎么设置端口映射
  5. 推荐爱码哥移动开发平台十大常用的原生UI控件
  6. 基于驱动框架编写驱动代码
  7. Afterlogic xmail 邮局软件不能收email 设置
  8. 【MySQL】varbinary 真的比varchar 更合适
  9. Linux云服务器VPS一键数据盘和系统盘合并磁盘方法
  10. mysql 删除的三种方法_mysql 删除表数据的三种方法