mysql死锁分析工具show engine innodb status

2023-11-11

 参考文章

《记录一次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 0
 0: 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 0
 0: 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 0
 0: 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);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql死锁分析工具show engine innodb status 的相关文章

  • 如何在每次运行 python 程序时添加新列

    我希望我的表的第一列作为卷号 第二列作为名称 每当我运行 python 程序时 我想在表中添加一列日期 在这个新列中 我想填充从 user list 获得的列表将包含值 P A P P 等 如何处理 我尝试首先通过 alter 命令添加一列
  • MySQL Workbench:如何将 mysql 数据库导出到 .sql 文件?

    我需要将 mysql 工作台中的数据库导出到文件 sql 该怎么办 在 MySql Workbench 版本 8 0 中 您只需按照以下步骤操作即可 Go to Server tab Go to 数据库导出 这会打开类似这样的东西 在中选择
  • golang sql 驱动程序的准备语句

    关于golang的sql driver 下面两条语句有什么区别 store DB is sql DB type rows err store DB Query SQL args err nil defer rows Close and st
  • Codeigniter,为MySQL创建表和用户

    我想以编程方式使用 CI 创建数据库和用户 到目前为止 我有这 2 个简单的 MySQL 语句 CREATE DATABASE testdb DEFAULT CHARACTER SET utf8 COLLATE utf8 general c
  • Knex 中的表的别名

    我有一个 SQL 查询两次引用同一个表 并且我需要将该表别名为两个单独的别名 我不太清楚如何用 Knex 来编写它 有一个 单词 表和一个 用户 表 Words 表有两个外键 author id 和 winner id 引用 Users 表
  • R dbGetQuery 与动态字符串

    From 这个帖子 https stackoverflow com questions 3416973 dynamic string in r and 这个帖子 https stackoverflow com questions 34496
  • 将多个子查询作为值插入

    假设我要插入一个有很多 fk 的表 只是为了在下面解释一下错误的说法 insert into mytable values somevalue somevalue select id from othertable1 where condi
  • SQL Server 2008 R2 中的字符映射/逐字符搜索和替换

    我在 SQL Server 2008 R2 上运行 我们在这里有一个要求 即我需要创建将某些英文字符替换为以前在遗留系统中使用的区域设置语言字符 为此 我可能会使用 T SQL 中的替换函数 但在我的实践中 我们会逐个字符地替换 例如 AS
  • MySQL 查询性能有帮助,许多相同的表被连接

    我正在编写一个创建 SQL 查询的 PHP 脚本 该脚本和数据库用于 Joomla CMS 特别是它查询 SOBIPro 组件的表 以使用在此组件中输入的数据 然而 由于 SOBI Pro 表的处理方式 字段的每个实例都是表中自己的行 这意
  • 通过 SSH 隧道远程访问 MySQL 数据库

    我正在尝试编写 Java 程序来使用 ssh 隧道访问远程 mySQL 数据库 下面是我的代码 int lport 5656 int rport 3306 String rhost 111 222 333 444 String host 1
  • 无法使用 Node.JS 将 null 值发送到 MySQL 数据库

    我正在尝试发送null使用 Node JS 到我的 MySQL 数据库 con query INSERT INTO Routes routeTrigger VALUES null title test function err result
  • 如何使用 php 命令使注册表单高度安全?

    我想让代码对用户来说真正安全 下面的代码显示了 php 代码 我已将其用于我的网站 现在我已经使用了一些验证 例如密码和重复密码必须匹配 并且用户必须输入所有字段 为了使其更安全 我想插入安全命令 例如 PDO mysqli crypto
  • 两个 mysql_fetch_array 语句

    是否有任何原因导致我无法在一个 while 循环中包含两个处理两个不同 mysql 查询结果的 mysql fetch array 语句 原因是我有两个来自 mysql 数据库的查询结果 每个结果包含两列 如下所示 Query 1 Date
  • Golang、mysql:错误1040:连接过多

    我正在使用 github com go sql driver mysql 驱动程序 我打开一个数据库 db err sql Open mysql str 然后我有两个函数 每个函数被调用 200 次 并使用以下 mysql 代码 rows
  • 如何为基于服务的数据库设置自动增量

    我在这里开始构建我的第一个本地数据库 基于服务的数据库 使用文本框将行写入基于服务的数据库 https stackoverflow com questions 39152801 write line to service based dat
  • (mysql, php) 如何在插入数据之前获取auto_increment字段值?

    我正在将图像文件上传到存储服务器 在上传之前 我应该编写文件名 其中包含自动增量值 例如 12345 filename jpg 在插入数据库之前如何获取自动增量值 我只看到一种解决方案 插入空行 获取其自增值 删除这一行 使用 p 1 中的
  • 将 1 添加到字段

    如何将以下 2 个查询变成 1 个查询 sql SELECT level FROM skills WHERE id id LIMIT 1 result db gt sql query sql level int db gt sql fetc
  • GoLang - 坚持使用 ISO-8859-1 字符集

    我正在开发一个项目 我们需要将信息保存在具有 ISO 8859 1 表的旧数据库中 因此 在向数据库写入内容之前 我需要将其从 UTF 8 转换为 ISO 8859 1 每次从数据库检索它时 我都需要将其转换回 UTF 8 我试图使用图书馆
  • 重命名 MySQL 中的表

    重命名表在 MySQL 中不起作用 RENAME TABLE group TO member 错误信息是 1064 You have an error in your SQL syntax check the manual that cor
  • 寻求有关标记视频系统上的“相关视频”查询的建议

    好吧 我运行一个小型视频网站 在实际的视频页面上有一条与大多数视频页面 例如 YouTube 类似的 相关视频 目前我所做的就是随机获取其标签之一并查找其他视频相同的标签 毫不奇怪 这不是一个好方法 因为有些标签非常模糊 有些视频被错误标记

随机推荐

  • 编写高质量代码:改善Java程序的151个建议(第8章:异常___建议110~117)

    不管人类的思维有多么缜密 也存在 智者千虑必有一失 的缺憾 无论计算机技术怎么发展 也不可能穷尽所有的场景 这个世界是不完美的 是有缺陷的 完美的世界只存在于理想中 对于软件帝国的缔造者来说 程序也是不完美的 异常情况会随时出现 我们需要它
  • 系统调用(int 0x80)详解

    1 系统调用初始化 在系统启动时 会在sched init void 函数中调用set system gate 0x80 system call 设置中断向量号0x80的中断描述符 define set system gate n addr
  • Python基础知识题库(带答案)

    单项选择题 第一章python语法基础 1 Python 3 x 版本的保留字总数是C A 27 B 29 C 33 D 16 2 以下选项中 不是 Python 语言保留字的是C A while B pass C do D except
  • python爬取网页的方法总结,python3.9爬取网页教程

    大家好 小编为大家解答python 爬取网页内容并保存到数据库的问题 很多人还不知道利用python爬取简单网页数据步骤 现在让我们一起来看看吧 需求分析 今天遇到一个简单的需求 需要下载澳大利亚电力市场NEM日前市场的发电商报价数据 ne
  • LeetCode题目笔记——965. 单值二叉树

    文章目录 题目描述 题目链接 题目难度 简单 方法一 遍历 哈希表 代码 Python 方法二 深度优先 代码 Python 总结 题目描述 如果二叉树每个节点都具有相同的值 那么该二叉树就是单值二叉树 只有给定的树是单值二叉树时 才返回
  • Field 'id' doesn't have a default value问题解决方法

    Field id doesn t have a default value问题解决方法 突然想温习温习对数据库的读写 于是就用mysql建了一张单独的表 见代码1 用Hibernate写了个应用 可以正常查询 修改数据了 开始时 数据是在m
  • IDEA——Java:程序包xxxx不存在终极方案总结

    最近在接手一个新的java项目 导入到IDEA后发现存在报错 程序包找不到 寻思应该是某些依赖没有加载进来 但几番尝试后发现问题依旧 于是决定调研下对应的解决方案 说实话类似这种问题的解决方案网上一搜一大堆 但试了很多根本不管用 其实大多数
  • Vue项目,通过数组下标更改数组的值不生效,页面没有重新渲染

    大家好 我是小梅 公众号 小梅的前端之路 原创作者 作为在前端领域不断探索的一员 在此记录开发中遇到的问题 如果你也遇到了相同的问题 希望本文对你有帮助 问题背景 今天在开发中遇到了一个需要 在列表里要通过按钮的点击控制手机号码列是显示正常
  • vue实现连接Mysql数据库和服务器通信

    在vue中 我们不仅是为了做前端页面展示和数据响应式 最重要的还是去访问后端请求 把数据给数据库存储 这样刷新页面数据才不会丢失 vue中对于数据的发送以及存储也很重要 稍不注意也会存在很大的问题 所以我们要学习一下存储数据以及对数据的请求
  • IDEA运行jar包不存在问题

    写在前面 本博客中解决方法适用情景为依赖包导入无错的情况下 即IDEA原因 解决方案 点击File gt Invaildate Cache Restart重启IDEA 2 若1无效 cmd路径切换到项目下执行mvn idea idea 再打
  • java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)

    报错信息 Exception in thread main java lang UnsupportedClassVersionError pers cyz BookManage has been compiled by a more rec
  • p值小于0.05拒绝还是接受_25常见种误区:P值、置信区间和统计功效

    连享会主页 lianxh cn 连享会 小直播 Stata 数据清洗 第二季 连享会 计量专题 因果推断 内生性 专题 2020 11 12 15 主讲 王存同 中央财经大学 司继春 上海对外经贸大学 课程主页 https gitee co
  • Shell笔记--使用系统函数、自定义函数和Shell工具

    目录 1 basename和dirname系统函数 2 自定义函数 3 Shell常用工具 3 1 cut 3 2 sort 1 basename和dirname系统函数 basename 基本用法 basename string path
  • LiveData的使用及详解

    1 LiveData简单使用 本篇文章代码实现部分主要使用Java进行讲解 LiveData主要方便用于数据的观察 进行UI更新或者业务处理等操作 如下为LiveData的简单代码实现 创建一个MutableLiveData对象 这个使用L
  • ModuleNotFoundError: No module named ‘pygame’——Python3.6安装pip并下载pygame模块

    问题 今天学习python的时候 运行时报错 ModuleNotFoundError No module named pygame 意思就是没有 pygame 这个模块 解决办法 下载一下这个模块就行了 pip3 install pygam
  • 给你一个电商网站,你如何测试?

    当下软件测试主流方向是Web端和移动端应用 但无论是哪个端 多数都可以基于软件测试的六个方向来测试 即功能 性能 易用性 可靠性 兼容性 有效性这几个方面考虑 如果给你一个电商网站 你该如何测试 以下是测试重点 文末有福利 一 功能测试 链
  • 光学基础知识:焦点、弥散圆、景深、焦深

    1 焦点 focus 与光轴平行的光线射入凸透镜时 理想的镜头应该是所有的光线聚集在一点后 再以锥状的扩散开 来 这个聚集所有光线的一点 就叫做焦点 2 弥散圆 circle of confusion 在焦点前后 光线开始聚集和扩散 点的影
  • 原生js 传数组作为参数 之get /post

    1 get 方式 var getData questionIDs qustionArr var questionArr questionArr push 12345678 定义一个函数 关键就在这里 原生的请求传数组是行不通的 需要将数据做
  • Excalidraw本地化部署

    Excalidraw本地化部署 官方地址 https excalidraw com 为什么要本地话部署呢 因为官方不支持中文手写体 Excalidraw介绍 Excalidraw是一个开源 小巧易用的手写风格的在线绘图工具 本地部署 在te
  • mysql死锁分析工具show engine innodb status

    参考文章 记录一次MySQL死锁的分析与解决过程 mysql之show engine innodb status解读 把MySQL中的各种锁及其原理都画出来 写在开头 本文为学习后的总结 可能有不到位的地方 错误的地方 欢迎各位指正 前言