温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

MySQL死锁场景实例分析

发布时间:2022-08-12 11:18:42 来源:亿速云 阅读:130 作者:iii 栏目:开发技术

这篇“MySQL死锁场景实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL死锁场景实例分析”文章吧。

1 环境准备

use martin;
drop table if exists dl;
CREATE TABLE `dl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`c` int(11) NOT NULL,  
PRIMARY KEY (`id`),
KEY `idx_c` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `dl_insert` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`c` int(11) NOT NULL,  
PRIMARY KEY (`id`),
unique key `uniq_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
insert into dl(a,b,c) values (1,1,1),(2,2,2);
drop table if exists dl_1;
create table dl_1  like dl;
insert into dl_1 select * from dl;

2 同一张表下的死锁

session1

session2

begin;

begin;

select * from dl where a=1 for update;…1 row in set (0.00 sec)

select * from dl where a=2 for update;…1 row in set (0.00 sec)

select * from dl where a=2 for update;/* SQL1 */(等待)

 

(session2 提示死锁回滚后,SQL1 成功返回结构)

select * from dl where a=1 for update;ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

commit;

commit;

session1 在等待 session2 释放 a=2 的行锁,而 session2 在等待 session1 释放 a=1 的行锁。两个 session 互相等待对方释放资源,就进入了死锁状态。

3 不同表下的死锁

session1

session2

begin;

begin;

select * from dl where a=1 for update; … 1 row in set (0.00 sec)

select * from dl_1 where a=1 for update; … 1 row in set (0.00 sec)

select * from dl_1 where a=1 for update;/* SQL2 */ 等待

 

(session2 提示死锁回滚后,SQL1 成功返回结构)

select * from dl where a=1 for update; ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

commit;

commit;

这个实验也是两个 session 互相等待对方释放资源,就进入了死锁状态。

4 间隙锁下的死锁

session1

session2

set session transaction_isolation='REPEATABLE-READ'; /* 设置会话隔离级别为 RR */

set session transaction_isolation='REPEATABLE-READ'; /* 设置会话隔离级别为 RR */

begin;

begin;

select * from dl where a=1 for update; … 1 row in set (0.00 sec)

select * from dl where a=2 for update; … 1 row in set (0.00 sec)

insert into dl(a,b,c) values (2,3,3);/* SQL1 */ 等待

 

(session2 提示死锁回滚后,SQL1 成功返回结果)

insert into dl(a,b,c) values (1,4,4);/* SQL2 */ ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

commit;

commit;

由于 RR 隔离级别下存在间隙锁,可以知道 SQL1 需要等待 a=2 获得的间隙锁,而 SQL2 需要等待 a=1 获得的间隙锁,两个 session 互相等待对方释放资源,就进入了死锁状态。

5 INSERT 语句的死锁

session1

session2

session3

begin;

  

insert into dl_insert(a,b,c) value (3,3,3);

  
 

insert into dl_insert(a,b,c) value (3,3,3);/* 等待 */

insert into dl_insert(a,b,c) value (3,3,3);/* 等待 */

rollback;

执行成功

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

这里需要注意的是,a 字段有唯一索引。当 session1 执行完 insert 语句,会在索引 a=3 上加记录锁,当 session2 执行同样的 insert 语句时,唯一键冲突,加上读锁;同样 session3 也会加上读锁。

当 session1 回滚,session2 和 session3 都试图继续执行插入操作,都要加上写锁。此时两个 session 都要等待对方的行锁,因此出现了死锁。

一些死锁场景就介绍到这里,当然,也欢迎各位补充其他的一些死锁场景。

以上就是关于“MySQL死锁场景实例分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI