Mysql报Deadlock found when trying to get lock; try restarting transaction问题解决

article/2025/10/31 0:37:14

Mysql报Deadlock found when trying to get lock; try restarting transaction问题解决!!

文章目录

  • 问题发生场景
  • Mysql锁类型分析
  • 死锁原理
  • 问题排查过程
  • 问题原因
  • 解决方法
  • 经验教训
  • 查看mysql死锁日志

问题发生场景

今天记录一下最近项目中遇到的一个问题,前几天在部署项目后,在线上运行过程中,突然报了入下这样的错误,从报错信息中我们可以看到,是mysql在执行update操作的时候报了一个死锁的问题,今天解决了,特此记录一下.

在这里插入图片描述

Mysql锁类型分析

MySQL有三种锁的级别:页级、表级、行级,这个地方我遇到的问题是来自于行级锁,所以重点说一下。

类型特性
表级锁 (table-level locking)开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁 (row-level locking)开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁 (page-level locking)开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

行级锁在使用的时候并不是直接锁掉这行记录,而是锁索引
如果一条sql用到了主键索引(mysql主键自带索引),mysql会锁住主键索引;
如果一条sql操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引.

死锁原理

mysql的两种锁排它锁(X锁)和共享锁(S锁)(mysql还有其他锁,需要了解可以自己去查,这个地方列举两个):

  • X锁,是事务T对数据A加上X锁时,只允许事务T读取和修改数据A,别的事务就没办法读取和修改,所以也叫排它锁,是互斥的
  • S锁,是事务T对数据A加上S锁时,其他事务只能再对数据A加S锁,而不能加X锁,直到T释放A上的S锁,别的事务也用加S锁,所以也叫共享锁,是不互斥的

一般造成死锁的原因是因为两个事物添加锁的时候没能及时的解锁释放资源,等到第二个事务要添加锁的时候发现已经被锁,从而造成环路等待,构成死锁条件。

问题排查过程

通过上面log日志中的报错信息,能很快确认报错的准确位置,
在这里插入图片描述
这个地方是执行了一个update的操作,我找到了了这个表,看了一下这个表的索引是有三个,两个非主键索引,一个主键索引.
在这里插入图片描述

果然,在图中这两条索引在那个update语句中都有进行的操作,具体如下
在这里插入图片描述
然后我又找了一下有可能会跟这条语句发生冲突的地方,果然在这个报错信息的上面,执行了一条这样的sql,这两条sql执行的间隔仅仅不超过1毫秒
在这里插入图片描述

根据上面所说的,如果一条sql用到了主键索引(mysql主键自带索引),mysql会锁住主键索引;
如果一条sql操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引.

因此sql(2)在使用的时候用到了schedu_id这个非主键索引,还需要锁定主键索引,然而此时sql(1)开始执行
,然后锁定了主键索引,但是在set操作中还用到了schedu_id这个非主键索引,但是这个索引在sql(1)执行的时候还在处于被锁的状态,因此两条sql就出现了对索引资源的竞争,造成了死锁.

问题原因

我的事务1中update wc_examine会多很多个update,这里有N行记录被锁定,事务的更新大量数据时间比较长,更新会加x锁,而此时事务2是UPDATE wc_examine ,在update之前先执行了select 操作,添加了S锁,然后想要update的时候添加X锁。

事务1的X锁正准备加上还是还没加上,实际是存在X锁,但是事务2加了s锁,事务1会等待事务2的s锁 事务2的完整事务加了s锁立即就要加x锁,但是事务1的x锁没有释放。造成了环路等待。

解决方法

这个地方,代码的问题需要根据情况自己去修改,

  1. 可以试着把索引去掉(有风险),
  2. 或者在进行update的时候尽量避开非主键索引

我这里记录一下被锁后应该怎么去解决的方法,首先先用sql查询一下mysql的事务处理表

select * from information_schema.INNODB_TRX  

在这里插入图片描述

正常情况下的状态都是RUNNING,但是在被锁之后就会变成LOCK WAIT ,一旦出现这种情况,就得杀死这个进程,如果进程杀不死就只能重启Mysql服务了
杀死进程

kill 进程ID

经验教训

无论前台后台的程序,都不应该存在仅根据非主键的几个字段一查就要update/delete的场景。即使有,也应该改为先把要更新的记录查出来然后逐条按主键id更新。

查看mysql死锁日志

show engine innodb status

找到信息中LATEST DETECTED DEADLOCK这一行,可以看到mysql的死锁信息详情

------------------------
LATEST DETECTED DEADLOCK
------------------------
2017-08-20 01:57:49 7fa264240700
*** (1) TRANSACTION:
TRANSACTION 309164542, ACTIVE 1 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 848
MySQL thread id 177543, OS thread handle 0x7fa26c0a0700, query id 698443941 192.168.96.32 root update
INSERT INTO kmsong.km_tbl_companygrandsong(CompanyID, SongID, SongDate) 
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 321 page no 13948 n bits 240 index `idx_companygrandsong_songid` of table `kmsong`.`km_tbl_companygrandsong` trx id 309164542 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 134 PHYSICAL RECORD: n_fields 2; compact format; info bits 00: len 8; hex 3030303234373631; asc 00024761;;1: len 8; hex 0000000000016dc8; asc       m ;;*** (2) TRANSACTION:
TRANSACTION 309164538, ACTIVE 2 sec fetching rows
mysql tables in use 1, locked 1
9714 lock struct(s), heap size 1275432, 632965 row lock(s), undo log entries 565
MySQL thread id 177544, OS thread handle 0x7fa264240700, query id 698448556 192.168.96.32 root updating
delete from kmsong.km_tbl_companygrandsong where CompanyID=-1 AND SongID='00053458'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 321 page no 13948 n bits 240 index `idx_companygrandsong_songid` of table `kmsong`.`km_tbl_companygrandsong` trx id 309164538 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 00: len 8; hex 73757072656d756d; asc supremum;;

可以很明显看出来是因为批量写入和删除产生了数据库死锁异常。


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

相关文章

死锁(Deadlock)

什么是死锁 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象。若无外力作用,它们都将无法推进下去。 产生死锁的四个必要条件得烂熟于心 互斥条件:进程要求对所分配的资源进行排他性控制,即在一段…

知识归纳:死锁

一. 死锁定义 死锁(Deadlock)是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。 举例:毕业生找工作,公司表示只需要有工作经验才可以来;要想有工作经验,就需要…

mmall数据库学习笔记

mmall数据库学习笔记 文章目录 mmall数据库学习笔记唯一索引产品表购物车表支付信息表订单表订单明细表收货地址表外键 唯一索引 在用户表中,设置了用户名作为唯一索引,理由如下:用户名是不允许重复的,那么当不是分布式开发的时候…

MMALL ADMIN 后台管理总结

后台管理项目前期准备 1,vue-cli2 项目框架 2,下载axios插件 cnpm install axios,安装Element.ui , vue-cli2中使用scss 注意版本 cnpm install sass-loader7.1.0 --save-dev (8.0.0) v…

mmall项目安装相关包文件

2019独角兽企业重金招聘Python工程师标准>>> 本步骤之前请先:建立相关文件夹(或者从git上clone项目下来),进入分支作业目录下运行个忠包文件的安装。注意:npm是所有安装的第一步 基础安装: 1.np…

mmall电商项目学习笔记之 idea,maven工程整合ssm框架

项目目录结构 1.pom文件导入jar包 1.1 <properties><!--设置编码格式--><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><!--sprin…

Demo_mmall v2.0 (四) Tomcat集群演进及使用Redis进行session重构实现单点登录

小谈mmall架构演进 上回书和上上回书说到redis的用法还有在代码里怎么操作Redis数据库&#xff0c;学完了得用啊。怎么用啊&#xff1f;这得从项目架构说起了。 mmall是一个简单的用SSM搭建起来的基本只能本地玩耍的电商DEMO&#xff0c;最简单的架构版本V1.0是这样婶的&#…

自学实践前后端项目4 MMall商城 2

一。搭建静态页面 1)UserController里面实现登录操作 Autowired private UserService userService;PostMapping("/login") public String login(String loginName, String password, HttpSession session){QueryWrapper wrapper new QueryWrapper();wrapper.eq(&q…

mmall用户模块

mmall用户模块 user数据表设计用户模块接口文档服务端响应对象&#xff08;ServerResponse< T>&#xff09;响应对象封装以下3个属性判断响应是否成功私有化构造函数&#xff0c;对外暴露静态方法返回所需要的响应对象&#xff0c;例如&#xff1a;响应成功响应失败 Resp…

自学实践前后端项目4 MMall商城 7

一。地址管理 1.前端改为 userAddress 2. OrderController增加两个需要的元素 3.接口 服务也加上去 4. 在OrderServiceImpl实现层判断是否为新地址再进行保存 //先判断新老地址 if (orders.getUserAddress().equals("newAddress")){//存入数据库UserAddress use…

自学实前后端践项目4 MMall商城 1

一.开发环境 1.JDK8以上Spring Boot 2.3.0ThymeleafMyBatis Plus3.3.1MySQL8.0 2.部署&#xff1a;Linux,&#xff0c;&#xff08;阿里云 腾讯云&#xff09;JDK8&#xff0c;MySQL8.0 3.部署方式&#xff1a;jar包部署&#xff0c;不需要Tomcat 二.新建工程 1&#xff0…

mmall电商项目学习笔记之mybatis三剑客

一.Mybatis plugin IDEA 2017.3版本下Mybatis plugin 3.53安装使用 插件下载地址 http://www.awei.org/download/iMybatis-3.21.jar 二.MyBatis-Generate 反向生成 【转】mybatis自动生成实体代码的插件 【method2】逆向生成 2.1 在pom.xml中做两处配置 2.1.1配置depen…

自学实践前后端项目4 MMall商城 4

一。实现商品详情展示 1.测试获取后台当个商品的信息 2.实现通过点击商品名称和商品图片进入商品详情页面 1&#xff09;查找出商品信息 2&#xff09;在前端进行映射 3&#xff09;设置库存选择限制 判断逻辑 $(function(){//给type绑定点击事件$(".type").click…

mmall 项目实战(一)项目初始化

1.创建 数据库 及 表 数据脚本&#xff1a; /* Navicat Premium Data Transfer Source Server : 182.92.82.103 Source Server Type : MySQL Source Server Version : 50173 Source Host : 182.92.82.103 Source Database : mmall Target Se…

B2C购物商城---MMALL商城概览

注意&#xff1a; 商品小图原图缺失后续上传到图片服务器。不影响使用支付宝二维码是支付宝沙箱开发环境生成&#xff0c;不会产生真实交易&#xff0c;若需体验&#xff0c;请下载支付宝沙箱版扫描体验项目仍需优化 本项目的完成参考了慕课网happymmall的设计 项目源码在&…

MMall项目完整分析总结

Linux服务器 线上环境&#xff1a; 1.jdk 2.vsftpd 3.nginx 4.mysql 5.tomcat 6.git 7.maven 8.Redis 项目采用Tomcat集群方式: 在此架构图中&#xff0c;nginx使用的是轮询的负载均衡策略。session不交给tomcat自己管理&#xff0c;已经交由左侧的redis分布式…

python flask-sqlalchemy flask-marshmallow基本使用

首先安装 pip install marshmallow-sqlalchemy pip install flask-sqlalchemy pip install flask-marshmallow 参考 sqlalchemy query 官网 app.py文件内容 from flask import Flask,jsonify import config from flask_sqlalchemy import SQLAlchemy from flask_marshmallow i…

Flask_使用flask_marshmallow序列化数据

代码如下&#xff1a; from flask import Flask from flask_marshmallow import Marshmallow from flask_sqlalchemy import SQLAlchemy from marshmallow import fieldsapp Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] "mysqlpymysql://root:12…

【Python】Marshmallow:Python中的“棉花糖”

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 文章目录 一、Marshmallow简介1.1、基础概念 二、序列化2.1、User类2.2、UserSchema类2.3、Serializing(序列化)2.4、运行2.5、过滤输出 三、反序列化四、验证数据4.1、V…

marshmallow——简介

一、marshmallow简介 在marshmallow诞生之前,已经有很多优秀的模块来用于数据的格式化和数据校验中。 因此书写mashmallow这个库的作者受这些库的启发,例如Django REST Framework, Flask-RESTful, 和colander这些。他同样从这些库中大量借用了设计和实现序列化、反序列化以及…