[MySQL] next-key lock 实践

文章探讨了在MySQL中,next-keylock在主键和唯一索引等值查询以及普通索引查询时的锁定策略,指出它会退化为行锁或间隙锁,确保索引范围内行记录的锁定。
摘要由CSDN通过智能技术生成

背景

探索next-key lock在唯一索引等值查询和普通索引等值查询的锁定情况

表结构

CREATE TABLE `test` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `c` int(11) NOT NULL DEFAULT '0' COMMENT '索引',
  `d` int(11) NOT NULL DEFAULT '0' COMMENT '非索引',
  PRIMARY KEY (`id`),
  KEY `idx_c` (`c`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='测试表'
INSERT INTO test
VALUES(0,0,0),
(5,5,5),
(10,10,10),
(15,15,15),
(20,20,20),
(25,25,25);

主键/唯一索引等值查询

(1)SQL1

BEGIN;
SELECT * FROM test WHERE id = '5' LOCK IN SHARE MODE;

(2)SQL2 ✅

 INSERT INTO test VALUES(6,6,6);

(3)SQL3 ❎

 UPDATE test SET d = 5 WHERE id = 5;

在SQL1事务COMMIT之前,SQL2执行成功;SQL3一直处于阻塞状态,无法完成更新操作。此时,SQL1持有以下锁:

  • SQL1持有了(0,5]的next-key lock,由于是唯一索引,会退化为行锁,锁定范围是id=5这一条行记录

SQL2
SQL3

普通索引等值查询

(1)SQL1

BEGIN;
SELECT * FROM test WHERE c = '5' LOCK IN SHARE MODE;

(2)SQL2 ❎

 INSERT INTO test VALUES(6,6,6);

(2)SQL3 ❎

 UPDATE test SET d = 5 WHERE id = 5;

在SQL1事务COMMIT之前,SQL2、SQL3一直处于阻塞状态,无法完成更新操作。此时,SQL1持有以下锁:

  • SQL1持有了(0,5]的next-key lock
  • SQL1持有了(5,10]的next-key lock,由于10不等于5,因此退化为(5,10)的间隙锁
    最终,SQL1持有锁定范围是(0,10)
    同时,证明了MySQL锁定的是索引范围内的行记录,而非索引?

SQL2
SQL3

总结

  • MySQL锁定的是索引范围内的行记录
  • next-key lock会在特定情况下退化为行锁或者间隙锁
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值