由delete语句引起的锁范围扩大

阿里云月报中的一句话,出处:http://mysql.taobao.org/monthly/2022/01/01/

但是Ghost Record是可以跟正常的Record一样作为Key Range Lock的加锁对象的。可以看出这相当于把删除操作变成了更新操作,因此删除事务不再需要持有Next Key Lock

这句话意思是:假设delete语句物理删除数据,那么delete事务会持有gap lock,那么会造成锁扩大,而实际上delete操作会转为update操作,最终delete事务持有的gap lock退化为record lock,不会造成锁范围扩大

下面用SQL Server和MySQL做测试,看一下锁的情况

SQL Server 2012

use test
go


CREATE TABLE t (
id int NOT NULL primary key,
c int DEFAULT NULL,
d int DEFAULT NULL
) CREATE NONCLUSTERED INDEX [ix_t_c] ON [dbo].[t]
(
[c] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO insert into t values(5,5,5),(10,10,10),(20,20,20),(25,25,25);

使用下面的执行顺序

在session1执行下面语句

--session 1
USE test
GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO begin transaction select id from t where c >10 and c <= 24 delete from t where c = 25 --commit

在session2执行下面语句

--session 2
USE test
GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO insert into t(id,c,d) values(27,27,27); (blocked)

申请的锁,情况如下

分析:首先我们要关注的加锁对象是二级索引【ix_t_c】,可以看到有三个range锁,这里锁住的范围是

rangeS-S(10,20]

rangeX-X(20, 25]

rangeS-U[25, +∞) 正无穷

正因为rangeS-U 锁,session 2的insert操作被阻塞了,也就是删除 c=25 这行数据,导致键范围锁扩大到 正无穷


MySQL 8.0.28

set global transaction isolation level REPEATABLE READ;
select @@global.transaction_isolation; use test; CREATE TABLE `t` (
`id` int(11) NOT NULL,
`c` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `c` (`c`)
) ENGINE=InnoDB; insert into t values(5,5,5),(10,10,10),(20,20,20),(25,25,25);

SQL语句执行顺序跟SQL Server一样

在session1执行下面语句

-- session 1
begin;
select id from t where c >10 and c <= 24 for update;
delete from t where c = 25; --commit

在session2执行下面语句

-- session 2
insert into t(id,c,d) values(27,27,27); (blocked)

申请的锁,情况如下

select * from performance_schema.data_locks\G
*************************** 1. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552409600:1217:140111564061632
ENGINE_TRANSACTION_ID: 7643
THREAD_ID: 331
EVENT_ID: 8
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140111564061632
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 2. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552409600:59:5:1:140111564058528
ENGINE_TRANSACTION_ID: 7643
THREAD_ID: 331
EVENT_ID: 8
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: c
OBJECT_INSTANCE_BEGIN: 140111564058528
LOCK_TYPE: RECORD
LOCK_MODE: X,INSERT_INTENTION
LOCK_STATUS: WAITING
LOCK_DATA: supremum pseudo-record
*************************** 3. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552408792:1217:140111564055552
ENGINE_TRANSACTION_ID: 7642
THREAD_ID: 330
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: NULL
OBJECT_INSTANCE_BEGIN: 140111564055552
LOCK_TYPE: TABLE
LOCK_MODE: IX
LOCK_STATUS: GRANTED
LOCK_DATA: NULL
*************************** 4. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552408792:59:5:1:140111564052496
ENGINE_TRANSACTION_ID: 7642
THREAD_ID: 330
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: c
OBJECT_INSTANCE_BEGIN: 140111564052496
LOCK_TYPE: RECORD
LOCK_MODE: X
LOCK_STATUS: GRANTED
LOCK_DATA: supremum pseudo-record
*************************** 5. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552408792:59:5:4:140111564052496
ENGINE_TRANSACTION_ID: 7642
THREAD_ID: 330
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: c
OBJECT_INSTANCE_BEGIN: 140111564052496
LOCK_TYPE: RECORD
LOCK_MODE: X
LOCK_STATUS: GRANTED
LOCK_DATA: 20, 20
*************************** 6. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552408792:59:5:5:140111564052496
ENGINE_TRANSACTION_ID: 7642
THREAD_ID: 330
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: c
OBJECT_INSTANCE_BEGIN: 140111564052496
LOCK_TYPE: RECORD
LOCK_MODE: X
LOCK_STATUS: GRANTED
LOCK_DATA: 25, 25
*************************** 7. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552408792:59:4:4:140111564052840
ENGINE_TRANSACTION_ID: 7642
THREAD_ID: 330
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: PRIMARY
OBJECT_INSTANCE_BEGIN: 140111564052840
LOCK_TYPE: RECORD
LOCK_MODE: X,REC_NOT_GAP
LOCK_STATUS: GRANTED
LOCK_DATA: 20
*************************** 8. row ***************************
ENGINE: INNODB
ENGINE_LOCK_ID: 140111552408792:59:4:5:140111564052840
ENGINE_TRANSACTION_ID: 7642
THREAD_ID: 330
EVENT_ID: 12
OBJECT_SCHEMA: test
OBJECT_NAME: t
PARTITION_NAME: NULL
SUBPARTITION_NAME: NULL
INDEX_NAME: PRIMARY
OBJECT_INSTANCE_BEGIN: 140111564052840
LOCK_TYPE: RECORD
LOCK_MODE: X,REC_NOT_GAP
LOCK_STATUS: GRANTED
LOCK_DATA: 25
8 rows in set (0.00 sec)

分析:这里我们要关注的加锁对象依然是二级索引【c】,这里MySQL的情况跟SQL Server一样

LOCK_MODE: X
LOCK_STATUS: GRANTED
LOCK_DATA: supremum pseudo-record

锁住的范围是 [25, +∞) 正无穷, 所以session 2的insert操作被阻塞了,也就是删除 c=25 这行数据,导致gap lock 扩大到 正无穷

通过上面两个测试,可以知道,即使delete操作在数据表中留下了Ghost Records,但是delete事务造成的gap lock范围没有缩小为Ghost Record的 record lock

因此,阿里云内核月报中的说法有失偏颇,误导读者

 

本文版权归作者所有,未经作者同意不得转载。

由delete语句引起的锁范围扩大的更多相关文章

  1. Mysql中truncate table和delete语句的区别

    Mysql中的truncate table和delete语句都可以删除表里面所有数据,但是在一些情况下有些不同! 例子: truncate table gag; (1)truncate table删除 ...

  2. MySQL-5.7 DELETE语句详解

    1.语法 (1)单表 DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [PARTITION (partition_name [, partit ...

  3. 追踪SQL Server执行delete操作时候不同锁申请与释放的过程

    一直以为很了解sqlserver的加锁过程,在分析一些特殊情况下的死锁之后,尤其是并发单表操作发生的死锁,对于加解锁的过程,有了一些重新的认识,之前的知识还是有一些盲区在里面的.delete加锁与解锁 ...

  4. 【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句

    原文:[SQL Server学习笔记]Delete 语句.Output 子句.Merge语句 DELETE语句 --建表 select * into distribution from sys.obj ...

  5. InnoDB 中不同SQL语句设置的锁

    锁定读.UPDATE 或 DELETE 通常会给在SQL语句处理过程扫描到的每个索引记录上设置记录锁.语句中是否存在排除该行的WHERE条件并不重要.InnoDB不记得确切的WHERE条件,但只知道哪 ...

  6. Sql Server系列:Delete语句

    数据的删除将删除表的部分或全部记录,删除时可以指定删除条件从而删除一条或多条记录.如果不指定删除条件,DELETE语句将删除表中全部的记录,清空数据表. 1 DELETE语法 [ WITH <c ...

  7. delete语句跑了3个小时分析以及关于并行的一些知识

    =====================START==================================== 闲来无事,看了下数据库跑的long running sql, SQL> ...

  8. SQL DELETE 语句

    DELETE 语句用于删除表中的行. 语法 DELETE FROM 表名称 WHERE 列名称 = 值 Person: LastName FirstName Address City Gates Bi ...

  9. MySQL DELETE语句和TRUNCATE TABLE语句的区别

    MySQL DELETE语句和TRUNCATE TABLE语句的区别 2010-10-08 16:05 佚名 互联网 字号:T | T 在MySQL数据库中,DELETE语句和TRUNCATE TAB ...

  10. 如何判断一条sql(update,delete)语句是否执行成功

    如何判断一条sql(update,delete)语句是否执行成功 catch  (SQLException    e)  {  }  catch不到错误应该就成功了.   ============== ...

随机推荐

  1. Vue cli路由

    上面是将Forecast组件作为了Home的子组件使用,现在我们将其作为一个路由组件使用. 在router/index.js路由系统注册路由: { path: '/forecast', name: ' ...

  2. LLM 大模型学习必知必会系列(十):基于AgentFabric实现交互式智能体应用,Agent实战

    LLM 大模型学习必知必会系列(十):基于AgentFabric实现交互式智能体应用,Agent实战 0.前言 **Modelscope **是一个交互式智能体应用基于ModelScope-Agent ...

  3. 使用kubadm部署一套k8s学习平台环境

    使用kubeadm部署k8s集群 环境 IP地址 主机名 节点 10.0.0.63 k8s-master1 master1 10.0.0.63 k8s-master2 master2 10.0.0.6 ...

  4. 如何实现sm3加密

    SM3加密应用 何为sm3加密? SM3是由中国国家密码管理局设计的一种密码杂凑函数,类似于SHA-256和MD5等国际标准的散列算法.SM3算法是中国国家标准<GB/T 32905-2016 ...

  5. kubernetes的搭建(一)

    集群的搭建 集群的类型 kubunetes的集群类型大致上分为两类: 一主多从和多主多从. 一主多从: 一台master节点和多台node节点,搭建简单,但是有单机故障的风险,适用于测试环境 多主多从 ...

  6. 数据库系列16:MyISAM与InnoDB的索引对比

    相关文章 数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩 ...

  7. bpmn.js

    在 BPMN.js 中,$inject 属性通常用于声明依赖注入的模块列表.这些模块会在创建对象实例时由依赖注入框架(如 AngularJS)提供.以下是在 BPMN.js 中常见的一些 $injec ...

  8. 剑指Offer-65.矩阵中的路径(C++/Java)

    题目: 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中的 ...

  9. Windows SERVER 新建FTP 服务器

    Windows SERVER 新建FTP 服务器 FTP主机上的操作(本机IP为:192.168.137.2): 1.新建一个名为 ftpa 的Windows用户. 2.在D盘新建一个 FtpBook ...

  10. TiDB 多集群告警监控-中章-融合多集群 Grafana

    author:longzhuquan 背景 随着公司XC改造步伐的前进,越来越多的业务选择 TiDB,由于各个业务之间需要物理隔离,避免不了的 TiDB 集群数量越来越多.虽然每套 TiDB 集群均有 ...