Mysql 死锁和死锁的解决方案

article/2025/9/28 2:47:39

最近在研究Mysql底层原理,研究到了死锁,感觉挺有意思,在这里和大家分享一下

前置知识:需要了解锁的种类,如表锁、行锁;行锁又分为记录锁、间隙锁、临键锁等等;什么情况下会加表锁,什么情况下会加行锁,什么情况下会加临键锁,什么情况锁会升级等等。。。网上讲解很多,这里就不单独讲述了

一 表死锁

产生原因:

用户A访问表A(锁住了表A),然后又访问表B;另一个用户B访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。
用户A–>A表(表锁)–>B表(表锁)
用户B–>B表(表锁)–>A表(表锁)

解决方案:

这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量按照相同的顺序进行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理, 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。

二 行死锁

产生原因1:

如果在事务中执行了一条没有索引条件的查询,引发全表扫描,把行级锁上升为全表记录锁定(等价于表级锁),多个这样的事务执行后,就很容易产生死锁和阻塞,最终应用系统会越来越慢,发生阻塞或死锁。

解决方案1:

SQL语句中不要使用太复杂的关联多表的查询;使用explain“执行计划"对SQL语句进行分析,对于有全表扫描和全表锁定的SQL语句,建立相应的索引进行优化。

产生原因2:

两个事务分别想拿到对方持有的锁,互相等待,于是产生死锁。
例如:
事务A
Begin;
     Select * from t1 where id = 1 for update;
     Update t1 set name = ‘aa’ where id = 5;
事务B
Begin;
     Delete from t1 where id = 5;
     Delete from t1 where id = 1;
事务A获取到了id=1的记录锁,执行update的时候,需要拿到id=5的锁;同时事务B拿到了id=5的记录锁,又需要拿到id=1的锁,因此两个事务同时进入无线阻塞状态,这就产生了死锁。

产生原因3:

   每个事务即使只有一个SQL,但是有些情况还是会发生死锁
   事务A,从name索引出发 , 读到的[hdc, 1], [hdc, 6]均满足条件, 不仅会加name索引上的记录X锁, 而且会加聚簇索引上的记录X锁, 加锁顺序为先[1,hdc,100], 后[6,hdc,10]
   事务B,从pubtime索引出发,[10,6],[100,1]均满足过滤条件,同样也会加聚簇索引上的记录X锁,加锁顺序为[6,hdc,10],后[1,hdc,100]。
   但是加锁时发现事务B跟事务A的加锁顺序正好相反,两个事务恰好都持有了第一把锁,请求加第二把锁,死锁就发生了。
如下图所示:
在这里插入图片描述

解决方案2、3:

上面的原因2和原因3出现死锁的原因, 都是对索引加锁顺序的不一致导致的,所以如果可以,尽量以相同的顺序来访问索引记录和表。在程序以批量方式处理数据的时候,如果事先对数据排序,保证每个线程按固定的顺序来处理记录,也可以大大降低出现死锁的可能;

三 死锁总结

  1. 对索引加锁顺序的不一致很可能会导致死锁, 所以如果可以, 尽量以相同的顺序来访问索引记录和表. 在程序以批量方式处理数据的时候, 如果事先对数据排序, 保证每个线程按固定的顺序来处理记录, 也可以大大降低出现死锁的可能.
  2. 间隙锁往往是程序中导致死锁的真凶, 由于默认情况下 MySQL 的隔离级别是 RR,所以如果能确定幻读和不可重复读对应用的影响不大, 可以考虑将隔离级别改成 RC, 可以避免 Gap 锁导致的死锁.
  3. 为表添加合理的索引, 如果不走索引将会为表的每一行记录加锁, 死锁的概率就会大大增大.
  4. 避免大事务, 尽量将大事务拆成多个小事务来处理. 因为大事务占用资源多, 耗时长, 与其他事务冲突的概率也会变高.
  5. 避免在同一时间点运行多个对同一表进行读写的脚本, 特别注意加锁且操作数据量比较大的语句.
  6. 设置锁等待超时参数:innodb_lock_wait_timeout,在并发访问比较高的情况下,如果大量事务因无法立即获得所需的锁而挂起,会占用大量计算机资源,造成严重性能问题,甚至拖跨数据库。我们通过设置合适的锁等待超时阈值,可以避免这种情况发生。

http://chatgpt.dhexx.cn/article/li9qqB3v.shtml

相关文章

mysql死锁演示

背景: 线上日志突然爆了有数据库死锁的日志。 通过以下语句查询数据库死锁的日志 SHOW ENGINE INNODB STATUS 通过 日志分析,看到了两条update语句并且是里面有子查询。还有两个表的更新顺序问题。 解决方案是:加了分布式锁,…

记录一次mysql死锁

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

深入MySQL死锁场景

总结死锁需满足以下条件: 2个或者2个以上的并发事务操作并发事务之间存在锁冲突锁冲突关系成环形 GAP锁和Insert的隐式锁,最容易导致死锁,以下分析从这俩典型场景开始。 1. 表结构 建立以下表作为场景验证,id为主键&#xff0…

mysql死锁查询语句

mysql 死锁:如何解决mysql死锁 可直接在mysql命令行执行:showengineinnodbstatus\G;查看造成死锁的sql语句,分析索引情况,然后优化sql然后showprocesslist;另外可以打开慢查询日志,linux下打开需在my.cnf的[mysqld]里面加上以下内…

MySQL死锁排查步骤

系列文章目录 第一章:sql_mode模式 第二章:optimize table、analyze table、alter table、gh-ost 第三章:InnoDB MVCC原理 第四章:sql语句执行过程 第五章:Percona Toolkit工具简介 第六章:MySQL索引 第七…

MySql死锁过程

死锁一般怎么导致呢, 抛开一堆概念, 我就把死锁当成死结。 就是你代码获取锁的顺序问题。 MySql的死锁和我们正常代码也一样, 都是互通的, 当你修改一个表的行数据的时候, 就需要对那一行数据进行加锁。 所以很容易想…

中秋遇到mysql死锁怎么办

文章目录 前言一、什么是死锁二、死锁的产生条件三、死锁示例四、死锁的分析和查看1.查看最近1个死锁信息2.查看正在运行中的事务信息3.查看加锁信息 五、死锁的内部处理方案1.死锁探测机制2.锁等待超时机制 六、手动释放锁1.表级锁手动释放2.行级锁手动释放 七、死锁的优化策略…

mysql 死锁分析

一、 什么是死锁 死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程.二、 死锁产生的四个必要条件 1.互斥条件:指进…

MySQL死锁分析

背景知识 MySQL数据库InnoDB引擎的行级锁在使用时是在索引记录上加锁的。 行级锁从占有模式上分为: 排他锁:独占行数据,如某事务获取了该行记录的排他锁,其他事务在获取该记录的排他锁和共享锁时需等待;共享锁&…

故障分析 | MySQL死锁案例分析

作者:杨奇龙 网名“北在南方”,资深 DBA,主要负责数据库架构设计和运维平台开发工作,擅长数据库性能调优、故障诊断。 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转…

MySQL死锁

参考博客: https://blog.csdn.net/sinat_41653656/article/details/109629094 Mysql 锁类型和加锁分析 MySQL有三种锁的级别:页级、表级、行级。 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大&#xff…

mysql死锁语句_Mysql死锁

笔者最近在生产环境错误日志上看到updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction 这样的日志 ,网上看了很多文章 发现这篇文章 跟自己的场景非常接近…

【MySQL锁篇】MySQL死锁问题以及解决方案

目录 一、MySQL出现死锁的场景 二、MySQL当中的死锁现象 三、Insert语句怎样加锁的 隐式锁&显示锁 记录之间加有间隙锁 遇到唯一键冲突或者主键冲突的时候加锁 如果主键索引重复: ​​​​​​如果唯一二级索引重复: 四、如何避免MySQL当中的死锁现象 方案…

mysql死锁介绍以及解决

什么是死锁 死锁是2个线程在执行过程中, 因争夺资源而造成的相互等待的现象,若无外力作用,它们将无法推进下去。 死锁产生的4个必要条件 互斥条件 指进程对所分配的资源进行排他性使用,即一段时间内某资源只有一个进程占用&#…

MySQL - 死锁的产生及解决方案

MySQL - 死锁的产生及解决方案 1. 死锁与产生死锁的四个必要条件1.1 什么是死锁1.2 死锁产生的4个必要条件 2. 死锁案例2.1 表锁死锁2.2 行锁死锁2.3 共享锁转换为排他锁 3. 死锁排查4. 实例分析4.1 案例描述4.2 案例死锁问题复现4.3 死锁排查4.4 解决死锁 5. 如何避免死锁 1. …

MySql 死锁

MySql 死锁 一、什么是死锁InnoDB存储引擎定义了四种类型的行锁隔离等级对加锁的影响当前数据对加锁的影响 二、为什么会形成死锁两阶段锁协议产生死锁的四个必要条件 三、MySQL 如何处理死锁?杀死进程MySQL表间隙锁排他锁共享锁分析行锁定行锁优化 四、如何避免发生…

论文阅读|SMPL2015

摘要: 我们提出了一个学习过的人体形状和姿势相关的形状变化模型,该模型比以前更准确建模并与现有的图形管线兼容。我们的蒙皮多人线性模型(SMPL)是基于蒙皮顶点的模型,可以准确地表示各种各样的人体姿态。模型的参数是…

densepose与SMPL之IUV坐标转XYZ坐标

具体流程 一、SMPL模型 SMPL模型拥有6890个XYZ坐标的3D人体点,目前第一步需要将这6890个人体点进行分析,并将不同部位的点位进行归并,具体分为以下几个部分:头部,胸部,腰部,左臂,右…

人体捕捉:《SMPL》

《SMPL: A Skinned Multi-Person Linear Model》 作者:Matthew Loper 主页:https://smpl.is.tue.mpg.de/ 时间:2015 文章目录 Table of NotationModel generation functionsModel input parameters(controls)Model parameters(parameters le…

python3跑通smpl模型_Python smpl-pytorch包_程序模块 - PyPI - Python中文网

Pythorch的SMPL层 SMPL人体[1]层为PyTorch(用v0.4和v1.x测试) 是一个可微的pytorch层,它确定地从姿势和形状参数映射到人体关节和顶点。 它可以作为可微层集成到任何体系结构中,以预测实体网格。 代码由Yana Hasson改编自manopth存储库。 安装 您可以从PyPI:安装smpl pytorc…