mysql 死锁案例及简略分析
准备数据
# 创一个测试表,存储引擎使用 innodb
create table test_lock (id int primary key auto_increment,name varchar(20),age int
)engine = innodb;insert into test_lock (name,age) values ('ionc001',10);
insert into test_lock (name,age) values ('ionc002',12);
insert into test_lock (name,age) values ('ionc003',13);
insert into test_lock (name,age) values ('ionc004',14);
insert into test_lock (name,age) values ('ionc005',15);
insert into test_lock (name,age) values ('ionc006',16);
insert into test_lock (name,age) values ('ionc007',17);
insert into test_lock (name,age) values ('ionc008',18);
insert into test_lock (name,age) values ('ionc009',19);
insert into test_lock (name,age) values ('ionc010',20);
死锁案例
- 执行事务前的数据
select * from test_lock;
| id | name | age |
|---|---|---|
| 1 | ionc001 | 10 |
| 2 | ionc002 | 12 |
| 3 | ionc003 | 13 |
| 4 | ionc004 | 14 |
| 5 | ionc005 | 15 |
| 6 | ionc006 | 16 |
| 7 | ionc007 | 17 |
| 8 | ionc008 | 18 |
| 9 | ionc009 | 19 |
| 10 | ionc010 | 20 |
- 事务执行过程
| 执行次序 | 事务 1 | 描述 | 事务 2 | 描述 |
|---|---|---|---|---|
| 1 | begin; | 事务 1 开启显式事务 | ||
| 2 | begin; | 事务 2 开启显式事务 | ||
| 3 | update test_lock set age = 100 where id = 1; | 事务 1 执行更新id = 1的记录 | ||
| 4 | update test_lock set name = ‘william’ where id = 2; | 事务 2 执行更新id = 2的记录 | ||
| 5 | update test_lock set name = ‘tx_1’ where id = 2; | 事务 1 执行更新,此时事务1会被事务2 阻塞 | ||
| 6 | update test_lock set age = 200 where id = 1; | 此条记录执行时,会报错,终止实物且整个事务回滚 | ||
| 7 | 由于事务 2 执行导致死锁,接着被 mysal检测到,终止事务 2 的执行,此时事务 1 继续执行 | |||
| commit; |
- 执行事务后的数据
| id | name | age |
|---|---|---|
| 1 | ionc001 | 100 |
| 2 | tx_1 | 12 |
| 3 | ionc003 | 13 |
| 4 | ionc004 | 14 |
| 5 | ionc005 | 15 |
| 6 | ionc006 | 16 |
| 7 | ionc007 | 17 |
| 8 | ionc008 | 18 |
| 9 | ionc009 | 19 |
| 10 | ionc010 | 20 |
show engine innodb status;
锁日志分析
=====================================
------------------------
LATEST DETECTED DEADLOCK # 上一次检测到的死锁
------------------------
2025-01-03 23:02:12 0x700010112000 # 时间
*** (1) TRANSACTION: # 事务 1
# 事务 ID,活跃时间
TRANSACTION 16535, ACTIVE 25 sec starting index read
# 表示当前事务使用了一个表,有一个表级锁(意向锁,有事务执行行级产生)
mysql tables in use 1, locked 1
# 表示表链中存在 3 个锁 (一个意向锁),堆大小,2 个行级锁,undo 日志一条
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
# 当前事务的线程id 及 执行的 SQL 语句,从语句看出来这是事务 1 的执行信息
MySQL thread id 14, OS thread handle 123145582202880, query id 2802 localhost 127.0.0.1 root updating
/* ApplicationName=DataGrip 2024.1.3 */ update test_lock set name = 'tx_1' where id = 2*** (1) HOLDS THE LOCK(S): # 持有的锁信息
# 记录锁,空间 ID,页码,事务 ID,锁模式 X lock(记录锁)且非间隙锁
RECORD LOCKS space id 368 page no 4 n bits 80 index PRIMARY of table `my_demo`.`test_lock` trx id 16535 lock_mode X locks rec but not gap
# 记录锁
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 80000001; asc ;; # 主键索引 11: len 6; hex 000000004097; asc @ ;; # 事务 ID 十六进制 4097 转 十进制 165352: len 7; hex 010000008f03bd; asc ;; # 回滚指针3: len 7; hex 696f6e63303031; asc ionc001;; # 本事务要更新的行记录的字段的值 ionc0014: len 4; hex 80000064; asc d;; # 本事务要更新的行记录的字段的值 十六进制 64 转 十进制 100*** (1) WAITING FOR THIS LOCK TO BE GRANTED:事务 1 等待事务 2 释放锁
RECORD LOCKS space id 368 page no 4 n bits 80 index PRIMARY of table `my_demo`.`test_lock` trx id 16535 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
# 下面信息是事务 2 的执行信息0: len 4; hex 80000002; asc ;;# 主键索引 21: len 6; hex 000000004098; asc @ ;;# 事务 ID 十六进制 4098 转 十进制 165362: len 7; hex 02000000cc11ab; asc ;;# 回滚指针3: len 7; hex 77696c6c69616d; asc william;;# 本事务要更新的行记录的字段的值 william4: len 4; hex 8000000c; asc ;; # 本事务要更新的行记录的字段的值 十六进制 c 转 十进制 12*** (2) TRANSACTION:
TRANSACTION 16536, ACTIVE 19 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 15, OS thread handle 123145582505984, query id 2811 localhost 127.0.0.1 root updating
/* ApplicationName=DataGrip 2024.1.3 */ update test_lock set age = 200 where id = 1*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 368 page no 4 n bits 80 index PRIMARY of table `my_demo`.`test_lock` trx id 16536 lock_mode X locks rec but not gap
Record lock, heap no 3 PHYSICAL RECORD: n_fields 5; compact format; info bits 00: len 4; hex 80000002; asc ;; # 主键索引 21: len 6; hex 000000004098; asc @ ;; # 事务 ID 十六进制 4098 转 十进制 165362: len 7; hex 02000000cc11ab; asc ;;# 回滚指针3: len 7; hex 77696c6c69616d; asc william;;# 本事务要更新的行记录的字段的值 william4: len 4; hex 8000000c; asc ;;# 本事务要更新的行记录的字段的值 十六进制 c 转 十进制 12*** (2) WAITING FOR THIS LOCK TO BE GRANTED: # 事务 2 等待事务 1 释放锁
RECORD LOCKS space id 368 page no 4 n bits 80 index PRIMARY of table `my_demo`.`test_lock` trx id 16536 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
# 下面信息是事务 1 的执行信息,0: len 4; hex 80000001; asc ;;1: len 6; hex 000000004097; asc @ ;;2: len 7; hex 010000008f03bd; asc ;;3: len 7; hex 696f6e63303031; asc ionc001;;4: len 4; hex 80000064; asc d;;*** WE ROLL BACK TRANSACTION (2) # 决定回滚事务 2
------------
TRANSACTIONS
------------
Trx id counter 16538
Purge done for trx's n:o < 16538 undo n:o < 0 state: running but idle
# ... 省略后面信息
END OF INNODB MONITOR OUTPUT
============================
开启死锁日志的持久化
- 默认情况下,上面显示引擎状态的命令,只会显示最近一次的死锁记录,可以使用下面命令查看死日志的记录参数的值,默认是关闭的
show variables like '%innodb_print_all_deadlocks%'; # off
- 开启死锁的错误日志记录
set global innodb_print_all_deadlocks = 'ON';
避免死锁的建议
避免死锁的方式,归根到底还是减少资源竞争。
- 时间上:耗时事务拆分,减少单个事务的耗时
- 空间上:事务操作的数据行尽可能的小,结果集尽可能小,减少联表操作等
- 合理使用索引,尽量把区分度高的列放到组合索引的前面(基于最左匹配原则),使得SQL 尽可能使用索引定位到最小的行(结果集),减少锁竞争。
- 调整业务逻辑 SQL 的执行顺序,把耗时操作放到后面执行,如 update语句。
- 事务拆分、避免事务执行逻辑过多,减少持锁周期。
- 在高并发的系统中不要显示加锁,能不在事务中加锁就不加锁。
相关文章:
mysql 死锁案例及简略分析
准备数据 # 创一个测试表,存储引擎使用 innodb create table test_lock (id int primary key auto_increment,name varchar(20),age int )engine innodb;insert into test_lock (name,age) values (ionc001,10); insert into test_lock (name,age) values (ionc00…...
第四届计算机、人工智能与控制工程
第四届计算机、人工智能与控制工程 The 4th International Conference on Computer, Artificial Intelligence and Control Engineering 重要信息 大会官网:www.ic-caice.net 大会时间:2025年1月10-12日 大会地点:中国合肥 (安徽大学磬苑…...
RIP配置实验
RIP配置实验 案例简介 天一公司下属三个分公司,属于不同的地区,三个公司之间用路由器连接,路由器名称分别为分别为 Router0、Router1、Router2,请把一公司的部门pc0,通过二公司路由器,连接三公司的部门pc1,公司之间通…...
C# 整型、浮点型 数值范围原理分析
总目录 前言 一、整型、浮点型 数值范围列表 二、什么是大小、范围 在上面的列表中,每个数据类型都有自己的Range (范围) 和 Size (大小)。 1. 范围 范围好理解,就是对应数据类型的数据范围,如 sbtyte 的数据范围是 -128~127,超…...
Adobe Acrobat Pro DC 2023 下载安装教程,附详细图文
简介: Adobe Acrobat Pro DC 2023 是由 Adobe 公司推出的一款全面的 PDF 编辑、查看和管理软件。这款软件无论是个人用户还是企业级用户,都可以凭借其强大的功能满足不同的需求。作为一款业内领先的 PDF 处理工具,Adobe Acrobat Pro DC 不仅…...
stable diffusion秋叶启动器安装roop插件
方法简洁明了: 第一步:下载秋叶启动器 第二步:输入网址:https://visualstudio.microsoft.com/zh-hans/downloads/,下载vs安装程序,安装开始会自动弹出如下窗口,选择2个环境:Python开…...
7-14 统计工龄
给定公司多名员工的工龄,按输入工龄顺序输出每个工龄段有多少员工。 输入格式: 给出多个整数,即每个员工的工龄,范围在[0, 50]。 输出格式: 按输入工龄顺序输出每个工龄的员工个数,格式为:“工龄:人数”。 每项占一…...
OLED的显示
一、I2C I2C时序:时钟线SCL高电平下:SDA由高变低代表启动信号,开始发送数据;SCL高电平时,数据稳定,数据可以被读走,开始进行读操作,SCL低电平时,数据发生改变࿱…...
本地测试文件解析
PostMapping("/test") public void test() throws IOException {Path csvFile Paths.get("D:\\test/27.csv");//虚拟机退出时删除临时文件csvFile.toFile().deleteOnExit();List<String> list Files.readAllLines(csvFile, Charset.forName("…...
Elasticsearch JavaRestClient版
文章目录 初始化RestHighLeveClient(必要条件)索引库操作1.创建索引库(4步)2.删除索引库(3步)3.判断索引库是否存在(3步)4.总结:四步走 文档操作1.创建文档(4…...
ubuntu 使用s3fs配置自动挂载对象存储
一、环境准备 1.有访问对象存储权限的AKSK 2.服务器、对象存储 二、实施步骤 sudo apt update sudo apt install s3fs echo "AK:SK" >/home/ubuntu/.passwd-s3fs ---位置自定义 chmod 600 /home/ubuntu/.passwd-s3fs ---权限必须要有 mkdir /data sudo s3fs …...
SQL字符串截取函数——Left()、Right()、Substring()用法详解
SQL字符串截取函数——Left()、Right()、Substring()用法详解 1. LEFT() 函数:从字符串的左侧提取指定长度的子字符串。 LEFT(string, length)string:要操作的字符串。length&#x…...
关系分类(RC)模型和关系抽取(RE)模型的区别
目标不同 关系分类模型:对给定的实体对在给定句子中预测其关系类型。两阶段(RC) 关系抽取模型:从句子中识别出所有潜在实体对,并为其预测关系类型。一阶段(NERRE) 训练/预测阶段输入输出数据不…...
什么是索引
在数据库管理系统中,索引是一种数据结构,用于快速定位数据库表中的特定记录。索引类似于一本书的目录,可以帮助数据库引擎迅速找到所需的数据,而不必扫描整个表。 类型:常见的数据库索引类型包括B树索引、哈希索引、全…...
OJ随机链表的复制题目分析
题目内容: 138. 随机链表的复制 - 力扣(LeetCode) 分析: 这道题目,第一眼感觉非常乱,这是正常的,但是我们经过仔细分析示例明白后,其实也并不是那么难。现在让我们一起来分析分析…...
UE5材质节点Distance
Distance可以计算两个物体间的距离,可以用来做过渡效果 当相机和物体距离3000的时候,就会渐渐从蓝过渡到红色,除以500是为了平滑过渡...
OSPF - SPF算法简述
SPF全称最短路径树算法,相信学过数据结构朋友应该看起来很熟悉 在一个区域内的路由器都会产生描述自己网络连接信息的LSA,包括两种信息,有路由信息和拓扑信息,简单的来说拓扑信息就是我连着谁,路由信息就是链路的地址…...
7.UE5横板2D游戏,添加分类,创建攻击,死亡逻辑,黑板实现追击玩家行为
目录 1.将变量分类 2.创建攻击 3.应用伤害逻辑 4.死亡逻辑,停止AI行为 5.AI追击玩家,使用黑板实现 1.将变量分类 2.创建攻击 创建攻击输入为鼠标左键,并绑定映射。 攻击动画,在角色状态的枚举中添加一个新的枚举 攻击输入的…...
PostgreSQL对称between比较运算
本文介绍PostgreSQL对称between比较功能:between symmetric,在动态拼接SQL时利用它可以简化判断。PostgreSQL 9.4 及以上版本支持BETWEEN SYMMETRIC操作符,MySQL、Oracle、MsSQL没有对应功能。 between 比较 PostgreSQL的between结构允许你对…...
Spring AOP面向切面编程
Spring AOP面向切面编程 面向切面编程AOP作用AOP功能AOP总结 AOP核心概念AOP的实现方式Spring 对AOP支持支持Aspect声明一个切面声明一个切入点AspectJ描述符如下AspectJ类型匹配的通配符常用的匹配规则 声明增强 用AOP实现日志拦截一般的实现仅拦截需要的方法先定义一个日志注…...
在AirSim里用Python实现LQR控制:让无人机自动跟踪预设轨迹(附完整代码)
用Python实现AirSim无人机LQR轨迹跟踪:从理论到代码落地 1. 环境准备与基础概念 在开始编写代码之前,我们需要先搭建好开发环境并理解几个核心概念。AirSim是微软开源的无人机/车辆仿真平台,基于Unreal Engine构建,提供了高度逼真…...
MySQL--Day02
约束 约束是作用于表中字段上的规则,用于限制存储在表中的数据 为了保证数据库中数据的正确性、有效性、完整性非空约束 NOT NULL唯一约束 UNIQUE主键约束 PRIMARY KEY默认约束 DEFAULT检查约束 CHECK CREATE TABLE user(id int primary key auto_increm…...
如何用代码思维提升90%图表效率?揭秘Mermaid的可视化革命
如何用代码思维提升90%图表效率?揭秘Mermaid的可视化革命 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-live-edi…...
UE4实战:利用VaRest与VictoryBPLibrary实现高效本地文件读写
1. 为什么需要本地文件读写 在虚幻引擎4开发过程中,我们经常需要保存游戏配置、玩家进度或者关卡数据。想象一下你正在开发一个RPG游戏,需要记录玩家背包里的所有物品、当前任务进度和角色属性。如果每次退出游戏这些数据都消失,玩家肯定会抓…...
W25Q16 Flash存储器:从基础概念到SPI通信实战
1. 认识W25Q16 Flash存储器 第一次接触W25Q16是在做一个智能家居项目时,需要保存用户的WiFi配置和房间温湿度记录。当时试过用单片机内部的EEPROM,但容量太小不够用,后来发现了这款性价比超高的外部Flash芯片。简单来说,W25Q16就像…...
手把手教你用n8n和Gemini 2.5 Flash搭建英语作文批改机器人(附完整工作流JSON)
从零构建AI英语作文批改系统:基于n8n与Gemini的自动化实践 在数字化教育浪潮中,教师面临的最大挑战之一是如何高效处理大量学生作业。英语作文批改尤其耗时——需要逐字阅读、语法检查、内容评估,最后还要给出建设性反馈。传统方式下…...
UE5.0.3打包Linux报错?手把手教你搞定BlueprintJson插件缺失问题
UE5.0.3 Linux打包报错终极指南:BlueprintJson插件问题的深度解析与实战修复 当你满怀期待地在UE5.0.3中点击"打包Linux"按钮,却看到屏幕上弹出关于BlueprintJson插件的红色错误信息时,那种挫败感我深有体会。作为一名经历过无数次…...
城通网盘限速破解:ctfileGet让下载效率提升10倍的技术革命
城通网盘限速破解:ctfileGet让下载效率提升10倍的技术革命 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet 在数字化协作日益频繁的今天,网盘已成为信息传递的重要枢纽。然而城通…...
XHS-Downloader:解决小红书内容高效采集难题的开源解决方案
XHS-Downloader:解决小红书内容高效采集难题的开源解决方案 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接…...
RWKV7-1.5B-G1A快速上手:5分钟部署你的轻量级文本生成助手
RWKV7-1.5B-G1A快速上手:5分钟部署你的轻量级文本生成助手 1. 为什么选择RWKV7-1.5B-G1A 如果你正在寻找一个轻量级但功能强大的文本生成模型,RWKV7-1.5B-G1A绝对值得考虑。这个基于RWKV-7架构的模型在1.5B参数规模下展现了出色的性能,特别…...
