【MySQL】之死锁问题及其解决方案

前言


数据库死锁问题是我们老生常谈的问题了,在我们实际开发过程中经常会遇到,为了尽量避免出现死锁,我们需要了解出现死锁的场景。同时,如果线上出现了死锁之后怎么去分析、排查和解决,下面我就这两点介绍一下。


一、数据库死锁介绍


1、什么是数据库死锁?

数据库的死锁是指:不同的事务在获取资源时相互等待,导致无法继续执行的一种情况。当发生死锁时,数据库系统会自动中断其中一个事务,以解除死锁。在数据库中,事务可以分为读事务和写事务。读事务只需要获取读锁,而写事务需要获取写锁。当多个事务同时操作同一组数据时,可能会引发死锁的出现。

2、MySQL 发生死锁的场景

2-1、事务同时更新多个表

当一个事务同时更新多个表并且使用了不同的顺序,可能会导致死锁的发生。例如,事务 A 首先更新表 X,此时获取到了 X 表的锁,并在未释放该锁的情况下尝试更新表 Y;而事务 B 首先更新表Y,此时获取到了 Y 表的锁,并在未释放锁的情况下尝试更新表 X。这种情况下,两个事务会相互等待对方的锁释放,从而形成死锁。

2-2、事务嵌套

当一个事务内部开启了另一个事务,并在内层事务中更新了某个表,而外层事务也需要更新该表的同一行记录时,就有可能发生死锁。因为外层事务需要等待内层事务释放锁,而内层事务需要等待外层事务释放锁。

2-3、索引顺序不一致

当多个事务按照不同的顺序访问相同的数据行,并且使用了不同的索引时,可能会发生死锁。例如,事务 A 按照索引 1 的顺序访问数据行,事务 B 按照索引 2 的顺序访问同一组数据行,这样两个事务之间就会产生死锁。

2-4、不同事务同时更新相同的索引

当多个事务同时更新相同的索引时,可能会导致死锁。这是因为事务在更新索引时会获取对应的锁,并在未释放锁的情况下尝试更新其他数据,从而形成死锁。


二、解决死锁问题


如果线上发生了死锁,我们应该采取以下步骤进行处理:

1、 监控死锁

正常情况下我们都会建立死锁监控机制,以便及时掌握死锁情况;同时设置相应的预警机制,以便在死锁发生时能够及时处理。

通过数据库的监控工具或命令可以查看是否存在死锁情况,如果出现则了解死锁的具体情况,包括死锁的事务和死锁的资源。

2、终止死锁事务

根据监控结果,找到造成死锁的事务,并手动选择其中一个事务终止。可以根据事务的执行时间、影响行数、优先级等因素进行终止决策。可以通过 select * from information_schema.innodb_trx 语句查看死锁情况。

在 innodb 中,有三张表可以帮助我们更好去分析死锁信息:

  • information_schema.innodb_trx:事务信息表。
  • information_schema.innodb_locks:事务锁的信息表。
  • information_schema.innodb_lock_waits:锁等待关系表。

系统自动解除死锁:

正常情况下,当发生死锁时,MySQL 系统会自动解除死锁,至于解除哪个事务的锁,需要亏了一个代价,在解除死锁方面,会选择回滚事务产生影响最小的一个进行回滚。

这里就要提一下两个概念了,一个是事务的权重trx_weight),另外一个是事务的调度权重trx_schedule_weight):

  • 事务的权重:与回滚事务的选择有关。具体与事务 undo 版本链的长度有关,回滚的 undo 记录越多,产生的影响就会越大,MySQL 就不会选择这样的事务,倘若事务权重一样,会选择事务等待队列等待时间短的事务进行回滚。
  • 事务的调度权重:与事务获取资源的先后有关。MySQL8.0.20 之前在等待锁的事务优先级排序采取 FIFO 算法,之后采取 CATS 算法。该算法通过分配调度权限对等待的事务进行优先级排序,该权重是根据事务阻塞的事务数量计算的。例如,两个事务正在等待同一对象上的锁,那么阻塞最多事务的事务将被分配更大的调度权重,如果权重相等,则优先考虑等待时间最长的事务分配资源。

3、重试事务

终止死锁事务后,需要重新执行被终止的事务。这可能需要一些逻辑处理,例如对数据进行回滚或者重新执行一些操作。

4、分析死锁原因

通过数据库的日志和监控信息,分析死锁的原因。下面是查看死锁日志的命令语句:

show engine innodb status;

分析死锁日志然后根据死锁原因对数据库的设计和代码进行优化,以尽量减少死锁的发生。

同时也可以根据分析结果,针对性地进行数据库结构调整、索引优化、事务隔离级别调整等措施,以降低死锁的概率。

5、避免死锁建议

  • 事务尽可能小,不要将复杂逻辑放进一个事务里。
  • 涉及多行记录时,约定不同事务以相同顺序访问。
  • 业务中要及时提交或者回滚事务,可减少死锁产生的概率。
  • 表要有合适的索引。
  • 可尝试将隔离级别改为 ReadCommit 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/212943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu22.04 怎么开启SSH服务

在 Ubuntu 22.04 LTS 中,默认情况下不会自动启动 SSH 服务。如果你想通过 SSH 访问你的 Ubuntu 系统,你需要手动安装 SSH 服务器,并确保 22 端口(SSH 的默认端口)是开放的。以下是必要的步骤: 安装 SSH 服…

Java 多线程之同步(锁)相关类总结

文章目录 一、概述二、volatile 可见性/有序性三、synchronized 互拆锁/排他锁/非观锁四、DCL(Double-Checked Locking)五、CAS(Compare and Set)六、ReentrantLock 可重入锁/公平/非公平锁七、ReentrantReadWriteLock 读写锁/共享…

Day56力扣打卡

打卡记录 数对统计&#xff08;DP状态压缩&#xff09; 参考文献 #include <bits/stdc.h>using namespace std;void solve(){int n;cin >> n;map<int, int> mapp;vector<int> a(n);for (auto& x : a){cin >> x;mapp[x] ;}vector<array&…

使用WebyogSQLyog使用数据库

数据库 实现数据持久化到本地&#xff1a; 使用完整的管理系统统一管理&#xff0c; 数据库&#xff08;DateBase&#xff09;&#xff1a; 为了方便数据存储和管理&#xff08;增删改查&#xff09;&#xff0c;将数据按照特定的规则存储起来 安装WebyogSQLyog -- 创建数…

101基于matlab的极限学习机ELM算法进行遥感图像分类

基于matlab的极限学习机ELM算法进行遥感图像分类&#xff0c;对所获取的遥感图片进行初步分类和最终分类。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。

如何使用 Explain 分析 SQL 语句?

如何使用 Explain 分析 SQL 语句&#xff1f; MySQL中EXPLAIN命令是我们分析和优化SQL语句的利器。 如何使用EXPLAIN来分析SQL语句&#xff0c;接下来有15个例子&#xff0c;一起学习呗 1. EXPLAIN的基本使用 EXPLAIN可以用于分析MySQL如何执行一个SQL查询&#xff0c;包括如…

ElasticSearch之cat repositories API

命令样例如下&#xff1a; curl -X GET "https://localhost:9200/_cat/repositories?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"执行结果输出如下&#xff1a; id type repo1 fs repo2 s3查…

python+gdal地理坐标转投影坐标

1 前言 地理坐标系&#xff0c;是使用三维球面来定义地球表面位置&#xff0c;以实现通过经纬度对地球表面点位引用的坐标系。 地理坐标系经过地图投影操作后就变成了投影坐标系。而地图投影是按照一定的数学法则将地球椭球面上点的经维度坐标转换到平面上的直角坐标。 2 流程…

基于STM32的四位数码管计数器设计与实现

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

Docker Compose(容器编排)——9

目录 什么是 Docker Compose生活案例为什么要 Docker ComposeDocker Compose 的安装Docker Compose 的功能Docker Compose 使用场景Docker Compose 文件&#xff08;docker-compose.yml&#xff09; 文件语法版本文件基本结构及常见指令Docker Compose 命令清单 命令清单如下命…

垃圾回收器CMS和G1的区别

CMS和G1的区别 区别一&#xff1a; 使用范围不一样 CMS收集器是老年代的收集器&#xff0c;可以配合新生代的Serial和ParNew收集器一起使用 G1收集器收集范围是老年代和新生代。不需要结合其他收集器使用 区别二&#xff1a; STW的时间 CMS收集器以最小的停顿时间为目标的收…

C++11(下)

可变参数模板 C11的新特性可变参数模板能够创建可以接受可变参数的函数模板和类模板. 相比C98/03, 类模版和函数模版中只能含固定数量的模版参数, 可变模版参数无疑是一个巨大的改进, 然而由于可变模版参数比较抽象, 使用起来需要一定的技巧, 所以这块还是比较晦涩的.掌握一些基…

Vue 3项目的运行过程

概述&#xff1a; 使用Vite构建Vue 3项目后&#xff0c;当执行yarn dev命令启动服务时&#xff0c;项目就会运行起来&#xff0c;该项目会通过src\main.js文件将src\App.vue组件渲染到index.html文件的指定区域。 文件介绍&#xff1a; src\App.vue文件 Vue 3项目是由各种组件…

递归实现指数型枚举

title: 递归实现指数型枚举 date: 2023-12-10 19:29:20 tags: 递归 catgories: 算法进阶指南 —> 传送门 题目大意 从 1 ~ n n n 这 n n n 个整数随机选取任意多个&#xff0c;输出所有可能的选择方案 思路 这等价于每个整数可以选或者不选&#xff0c;所有的方案总数共有…

Spring Boot的日志

打印日志 打印日志的步骤: • 在程序中得到日志对象. • 使用日志对象输出要打印的内容 在程序中得到日志对象 在程序中获取日志对象需要使用日志工厂LoggerFactory,代码如下: package com.example.demo;import org.slf4j.Logger; import org.slf4j.LoggerFactory;public c…

STM32——继电器

继电器工作原理 单片机供电 VCC GND 接单片机&#xff0c; VCC 需要接 3.3V &#xff0c; 5V 不行&#xff01; 最大负载电路交流 250V/10A &#xff0c;直流 30V/10A 引脚 IN 接收到 低电平 时&#xff0c;开关闭合。

Go Fyne 入门

Fyne是一个用于创建原生应用程序的UI工具包&#xff0c;它简单易用&#xff0c;并且支持跨平台。以下是一个简单的Fyne教程&#xff0c;帮助你入门&#xff1a; 1. 安装Fyne 首先&#xff0c;确保你已经安装了Go语言。然后&#xff0c;在终端中运行以下命令来安装Fyne&#x…

android-xml语法

xml解析器 Android的XML文件语法是由Android系统中的解析器解析的。具体来说&#xff0c;Android使用了一个名为"Android Asset Packaging Tool (AAPT)"的工具来解析和处理XML文件。AAPT负责将XML文件编译为二进制格式&#xff0c;并在构建过程中将其打包到Android应…

第2节:Vue3 模板语法

Vue3 的模板语法主要包括以下几个部分&#xff1a; 插值表达式&#xff1a;使用双大括号 {{ }} 包裹变量&#xff0c;可以直接在模板中显示变量的值。 <div>{{ message }}</div>指令&#xff1a;以 v- 开头&#xff0c;后面跟一个自定义的名字&#xff0c;用于操…

从Centos-7升级到Centos-Stream-8

如果在正式环境升级&#xff0c;请做好数据备份以及重要配置备份&#xff01;因为升级会造一部分应用被卸载。 注意&#xff1a;升级前请备份好数据&#xff0c;升级可能会导致ssh的root用户无法登陆、网卡名称发生改变、引导丢失无法开机等问题。 1.安装epel源 yum -y install…