死锁-MySQL

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 死锁 MySQL

1、死锁

在操作系统中,死锁是指两个或两个以上的进程,每个进程都无限等待被改组进程中另一个进程所占有的资源,因而永远无法得到资源,这种现象称为进程死锁。

那么在数据库中,我们将操作系统对死锁的定义进行简单替换,将进程替换为事务即可。

数据库死锁是指两个或两个以上的事务,每个事务都在无限等待被改组事务中另一个事务所占有的资源,因而无法得到资源。

2、死锁必要条件

只要发生了死锁,这四个条件一定存在。

  1. 互斥使用(独占资源)

在数据库中,互斥使用的资源大部分都是表和行。

  1. 占有且等待

一个事务先锁定了行A,然后又申请锁定行B;另一个事务先申请锁定了行B,然后有申请锁定行A;当这两个事务以一种时序执行时就会产生死锁。

  1. 不可抢占

事务与事务之间是隔离的,肯定不可以一个事务抢占另一个事务的资源,必须要等待事务资源释放资源。

  1. 循环等待

当事务和资源形成一条有向有环图时。使用资源分配图来表示一下(蓝色先表示有回路):

1.png

3、SQL示例


-- 创建用户余额表
CREATE TABLE `user_balance` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `balance` int NOT NULL COMMENT '余额',
  PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = '用户余额';

-- 插入2条记录
INSERT INTO `user_balance` (`balance`) VALUES (1);
INSERT INTO `user_balance` (`balance`) VALUES (1);


-- 事务A
BEGIN;
UPDATE `user_balance` SET `balance`=`balance`+1 where id=1;
UPDATE `user_balance` SET `balance`=`balance`+1 where id=2;
COMMIT;


-- 事务B
BEGIN;
UPDATE `user_balance` SET `balance`=`balance`+1 where id=2;
UPDATE `user_balance` SET `balance`=`balance`+1 where id=1;
COMMIT;

如果恰好事务A和事务B都执行了第一行UPDATE,接着事务A和事务B都去执行第二条UPDATE语句,此时发现id=1和id=2的数据都被锁定且不是自己,那么事务A和B都在相互等待锁释放,则陷入了死锁状态。

4、解决方案

为了解决死锁问题,数据库实现了各种死锁检测和死锁超时机制。InnoDB存储引擎可以检测到死锁的循环依赖并立即返回操作。

InnoDB目前处理死锁的方式是将持有最少行排他锁的事务进行回滚。

5、死锁复现

按照使用上面的SQL在MySQL 8.0版本执行SQL进行死锁复现,截图如下:

  1. 事务A正常执行

2.png

  1. 事务B被回滚

3.png

6、总结

  1. MySQL 的死锁并不可怕,死锁后只需要在业务代码进行重试即可(官方建议)

7、参考

  1. 高性能MySQL(第三版)
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
2月前
|
关系型数据库 MySQL Java
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
|
11月前
|
SQL 关系型数据库 MySQL
MySQL死锁及源码分析!
MySQL死锁及源码分析!
148 0
MySQL死锁及源码分析!
|
11月前
|
SQL 关系型数据库 MySQL
案例剖析:MySQL唯一索引并发插入导致死锁!
案例剖析:MySQL唯一索引并发插入导致死锁!
712 0
案例剖析:MySQL唯一索引并发插入导致死锁!
|
11月前
|
SQL 关系型数据库 MySQL
案例剖析,MySQL共享锁引发的死锁问题!
案例剖析,MySQL共享锁引发的死锁问题!
131 0
|
SQL 关系型数据库 MySQL
遇到mysql数据库死锁,你会怎么排查?
遇到mysql数据库死锁,你会怎么排查?
806 0
|
9月前
|
存储 关系型数据库 MySQL
从新手到高手:彻底掌握MySQL表死锁
通过本文的介绍,希望你能深入理解MySQL表死锁的概念、原因、检测方法及解决方案,并在实际开发中灵活应用这些知识,提升系统的稳定性和性能。
852 9
|
10月前
|
SQL 算法 关系型数据库
面试:什么是死锁,如何避免或解决死锁;MySQL中的死锁现象,MySQL死锁如何解决
面试:什么是死锁,死锁产生的四个必要条件,如何避免或解决死锁;数据库锁,锁分类,控制事务;MySQL中的死锁现象,MySQL死锁如何解决
|
11月前
|
关系型数据库 MySQL 数据库
一个 MySQL 数据库死锁的案例和解决方案
本文介绍了一个 MySQL 数据库死锁的案例和解决方案。
690 3
|
12月前
|
监控 关系型数据库 MySQL
MySQL锁机制与解决死锁问题
MySQL锁机制与解决死锁问题
566 5
|
11月前
|
监控 关系型数据库 MySQL
一次彻底讲清如何处理mysql 的死锁问题
【10月更文挑战第16天】本文详细介绍了如何处理 MySQL 中的死锁问题,涵盖死锁的概念、原因、检测方法及解决策略,强调通过优化事务设计、调整数据库参数、手动处理和预防措施等手段,有效减少死锁,提升数据库性能与稳定性。
1995 0

推荐镜像

更多