一个表,一条记录,也能玩出死锁!!!

2023年 9月 25日 37.5k 0

一、构造测试数据

CREATE TABLE `deadlock_test` (
id bigint NOT NULL ,
uid bigint not null,
deleted int not null,
PRIMARY KEY (id),
UNIQUE KEY `uk_uid` (uid)
)
insert into deadlock_test values(1,10,0);

select * from deadlock_test ;

如上所示,这个表只有一条记录。

二、构造死锁

session1 执行如下语句;

begin;
update deadlock_test set deleted = 1 where uid = 10 ;

session2 执行如下语句

begin;
update deadlock_test set uid = 1 where id = 1;

session3 执行如下语句

begin;
update deadlock_test set deleted = 1 where uid = 10 ;

再回到session1 执行

rollback;

这时候死锁产生

执行顺序如下表一样

三、死锁分析

借助 performance_schema.data_locks表来分析死锁的形成

session1执行后,产生两条锁记录
一个是主键索引上的X锁,一个是唯一键索引上的X锁

session2执行后
增加了一个 阻塞的主键锁

session3执行后
增加了一个 阻塞的唯一键锁

回到session1 执行回滚后
session2 与 session3产生了相互等待
session2语句要完成,不仅需要唯一键锁,还要主键锁;
session3语句要完成,不仅需要主键锁,还要唯一键锁;

session2 等待session3的唯一键锁
session3 等待session2的主键锁

至此死锁产生

死锁形成上图。

四、建议

对于表的更新,删除,尽量where条件扫描主键索引。 这样就不会造成死锁,只会阻塞。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论