mysql delete锁_MySQL DELETE 删除语句加锁分析

MySQL DELETE 删除语句加锁分析

http://www.fordba.com/lock-analyse-of-delete.html

1. 前言

在MySQL的使用过程中,对SQL加锁的类型经常感到疑惑,这让死锁分析也变得举步维艰。因此需要将MySQL的各种SQL在各个隔离级别下加的锁进行分析,以免再次分析的时候还感到疑惑,也方便用于查询。

本次分析对SQL的删除语句进行分析,主要从以下几种情况进行分析:非唯一索引删除一条存在的记录

唯一索引删除一条存在的记录

主键删除一条存在的记录

非唯一索引删除一条不存在记录

唯一索引删除一条不存在的记录

主键删除一条不存在的记录

不同的SQL根据主键删除2条记录

非唯一索引删除一条已经标记删除的记录

唯一索引删除一条已经标记删除的记录

在使用之前需要打开innodb lock monitor,这样在查看 engine innodb status 的时候可以更加清晰的查到到锁的情况

2. SQL的加锁分析

相关表结构普通索引表结构唯一索引表结构表的记录,唯一索引和普通索引的表结构均一样

测试的事务隔离级别为RR。

2.1 删除SQL加锁分析

根据非唯一索引删除一条存在记录

根据非唯一索引进行删除的时候,锁情况为:4 lock struct(s):4种锁结构,分别为IX,idx_c1和主键的行锁,还有idx_c1的gap锁

3 row lock(s):有3个行锁,除去IX的都是算在row lock里面

根据唯一索引删除一条存在记录

根据唯一索引进行删除的时候,锁情况为:3 lock struct(s):3种锁结构,分别为IX,idx_c1和主键的行锁,没有gap锁

2 row lock(s):有2个行锁,除去IX的都是算在row lock里面,没有gap,因此为2个

根据主键删除一条存在记录

根据主键进行删除的时候,锁情况为:2 lock struct(s):2种锁结构,分别为IX和主键的行锁,没有gap锁

1 row lock(s):有1个行锁,就主键记录上的行锁,没有gap,因此为1个

根据非唯一索引删除一条不存在 记录

根据非唯一索引删除一条 不存在 记录,锁情况为:2 lock struct(s):2种锁结构,分别为IX和X类型的gap锁

1 row lock(s):有1个行锁,为非唯一索引的gap锁

根据唯一索引删除一条不存在 记录

根据唯一索引删除一条 不存在 记录,发现和非唯一索引一样,锁情况为:2 lock struct(s):2种锁结构,分别为IX和X类型的gap锁

1 row lock(s):有1个行锁,为唯一索引的gap锁

根据主键删除一条不存在 记录

根据主键删除一条 不存在 记录,发现和非唯一索引一样,锁情况为:2 lock struct(s):2种锁结构,分别为IX和X类型的gap锁

1 row lock(s):有1个行锁,为主键上的gap锁

根据主键删除两条存在的记录

根据主键删除两条的时候,使用in的锁情况为:2 lock struct(s):2种锁结构,分别为IX和i主键的行锁,没有gap锁

2 row lock(s):有2个行锁,就主键记录上的行锁,没有gap,因此为2个

根据主键删除两条的时候,使用>,=,<=,比较符号的锁情况为:无论如何,匹配到2条记录,因此必须会有2 row lock(s)

如果只有>,

碰到 >= 的时候,判断 >= 的值是否存在,如果存在,则锁定该记录。所以除了IX,X锁,还有行锁,因此存在的时候为3 lock struct(s), 3 row lock(s)。如果不存在,和第二种是一样的,为2 lock struct(s) ,3 row lock(s) 。

非唯一索引删除一条已经标记删除的记录Sess1Sess2Sess3

begin;

delete from t where c1=8;

begin;

delete from t where c1=8;

@1 show engine innodb status

commit;

@2 show engine innodb status

非唯一索引删除一条已经标记删除的记录的锁情况为:加锁等待时: 2 lock struct(s) ,持有IX锁,等待记录上的X锁

加锁成功时:3 lock struct(s),持有IX,行锁,和gap锁,这个和非唯一索引删除一条不存在的记录是基本一样的,多了个因Sess1 提交成功后多获得的行锁。

唯一索引删除一条已经标记删除的记录Sess1Sess2Sess3

begin;

delete from tu where c1=8;

begin;

delete from tu where c1=8;

@1 show engine innodb status

commit;

@2 show engine innodb status

唯一索引删除一条已经标记删除的记录的锁情况为:加锁等待时: 2 lock struct(s) ,持有IX锁,等待记录上的X锁

加锁成功时:3 lock struct(s),持有IX,行锁,和gap锁,和非唯一索引删除一条标记为已删除的记录的情况一模一样。

3. 总结在非唯一索引的情况下,删除一条存在的记录是有gap锁,锁住记录本身和记录之前的gap

在唯一索引和主键的情况下删除一条存在的记录,因为都是唯一值,进行删除的时候,是不会有gap存在

非唯一索引,唯一索引和主键在删除一条不存在的记录,均会在这个区间加gap锁

通过非唯一索引和唯一索引去删除一条标记为删除的记录的时候,都会请求该记录的行锁,同时锁住记录之前的gap

RC 情况下是没有gap锁的,除了遇到唯一键冲突的情况,如插入唯一键冲突。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值