由delete引起的锁扩大[亲测有效]

由delete引起的锁扩大[亲测有效]由delete引起的锁扩大 阿里云月报中的一句话,出处:http://mysql.taobao.org/monthly/2022/01/01/ 但是Ghost Record是可以跟正常的Record一

由delete引起的锁扩大

由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);

 

使用下面的执行顺序

由delete引起的锁扩大[亲测有效]

 

 

在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)

申请的锁如下

由delete引起的锁扩大[亲测有效]

分析:首先我们要关注的加锁对象是二级索引【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_locksG
*************************** 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】,这里跟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引起的锁扩大[亲测有效]

原文地址:https://www.cnblogs.com/lyhabc/archive/2022/02/24/15883562.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/5487.html

(0)
上一篇 2023-05-07
下一篇 2023-05-07

相关推荐

  • Java中使用Jedis连接Redis对SortedSet进行排序操作

    Java中使用Jedis连接Redis对SortedSet进行排序操作场景 Centos中Redis的下载编译与安装(超详细): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103967334 Re

    2023-02-08
    155
  • 使用Python for循环轻松迭代序列

    使用Python for循环轻松迭代序列Python语言中for循环是一种用来遍历各种序列类型的迭代工具,极大地简化了程序员的工作。在本文中,我们将深入探讨此功能并展示如何用Python语言进行循环迭代。

    2023-12-09
    116
  • mysql的安全性机制_系统可靠性模型分为哪几种

    mysql的安全性机制_系统可靠性模型分为哪几种Mysql 主要通过binlog 跟redolog 来保证数据的可靠性 binlog 的写入机制 binlog 的写入逻辑比较简单:事务执行过程中,先把日志写到 binlog cache,事务提交的…

    2023-01-26
    154
  • 计算 存储 分离_一文读懂什么是IND

    计算 存储 分离_一文读懂什么是IND摘要:IDC认为,目前阶段来看,企业亟待解决的是数字化能力提升,包括:与业务的深入结合能力;数据处理和挖掘能力;以及IT技术运营和管理能力。特别是数据处理和挖掘能力,因为数字化转型推进企业从以流程为…

    2023-04-04
    146
  • Python Class用于面向对象编程

    Python Class用于面向对象编程Python是一种简单易学的高级编程语言,常用于数据分析、机器学习、人工智能等领域。Python是一种面向对象的编程语言,具有强大的面向对象编程特性。Python中的Class是实现面向对象编程的重要组成部分,一个Class可以包含多个属性和方法,可以用来创建对象。下面将从多个方面对Python Class用于面向对象编程进行详细的阐述。

    2024-03-23
    82
  • 【漫画】ES原理 必知必会的倒排索引和分词「建议收藏」

    【漫画】ES原理 必知必会的倒排索引和分词「建议收藏」倒排索引的初衷 倒排索引,它也是索引。索引,初衷都是为了快速检索到你要的数据。 我相信你一定知道mysql的索引,如果对某一个字段加了索引,一般来说查询该字段速度是可以有显著的提升。 每种数据库都有自

    2023-03-04
    158
  • 手把手教你用策略模式 写echarts的配置项option

    手把手教你用策略模式 写echarts的配置项option前言:策略模式和适配器模式很像 但前者策略的接口和相关类会暴露出来,并且每个策略的“计算内容”都不同【常用于计算】。 一、研究下echarts官网的重要配置 1.1 常用项主要有title lege…

    2023-03-31
    149
  • 数据库基础-事务篇「终于解决」

    数据库基础-事务篇「终于解决」1、事务是什么 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。 2、事…

    2023-02-21
    147

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注