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

一直以为很了解sqlserver的加锁过程,在分析一些特殊情况下的死锁之后,尤其是并发单表操作发生的死锁,对于加解锁的过程,有了一些重新的认识,之前的知识还是有一些盲区在里面的。
delete加锁与解锁步骤是怎么样的?什么时候对那些对象,加什么类型的琐,加锁与索引的关系是怎么样的,什么时候释放锁?整个过程锁是如何参与整个delete操作过程表的?
这里通过一个非常简单的delete语句,来分析一条delete执行过程中加解锁的过程。

测试表创建

用一个最最简单的例子做了跟踪,对锁的申请和释放,有了更清晰的认识,这个过程非常有意思,看完之后会非常清晰地认识到delete语句执行过程中加解锁的步骤是怎么样的。
如果对一个SQL加解锁的步骤不清楚,解决死锁,只能说经验,或者说是靠蒙、亦或靠猜地去减少死锁的可能性。
如下脚本,创建测试表,待用。

跟踪的测试删除sql语句为:delete from  test_require_release_lock where col2 = ‘a999‘ and col3 = ‘b999‘,where条件的目标数据是1行,条件是用到where的第一个筛选条件的索引。

测试数据的基本信息

先拿到一些基本的信息对象id,索引Id,key值等物理Id(RowHashId)等等,这些Id稍后会清晰地展示在profile跟踪日志中,能帮助我们去了解到底在什么对象(数据行,索引行)加什么类型的锁。

当前值得物理地址(RowHashId)

Profile跟踪日志

如下是profile跟踪出来的delete from test_require_release_lock where col2 = ‘a999‘ and col3 = ‘b999‘语句执行过程中表级别锁的申请和释放
我只能说:这个case包括数据,是反复测试各种情况之后,最最简单的一种情况了,稍微复杂一点的情况,对于一行数据的删除,加解锁的过程至少要两屏才能显示出来。

加解锁过程分析

这个过程可以大致分为3个阶段,仅仅执行一条数据删除的delete语句,就有37步之多,为了简化这个过程,这里只看数据行上的加解锁信息,如图所示的前23步。
阶段1:根据where条件查找数据的物理Id,也即RID,这个过程是IU/U锁。虽然执行的是delete,此过程不删任何数据,只是根据条件,找到数据的RID
阶段2:依次删除数据行和索引行,也即依次删除RID,主键索引,多个索引键索引,这个过程涉及到第一步的IU/U锁转换IX/X以及新申请IX/X锁,以及锁释放
阶段3:(删除完成)依次释放之前步骤申请尚未释放的锁

如下是profile中这个过程中每一步的说明

阶段1:
1,申请基表82099333上意向IX锁
2,申请目标行索引字段col2(fe51867f3259)所在page的IU锁
3,申请目标行索引字段col2(fe51867f3259)Key级别的U锁
4,申请目标所索引字段col2(fe51867f3259)对应的RID所在page的IU锁
5,申请目标所索引字段col2(fe51867f3259)对应的RID行的RID的U锁
阶段2
6,升级4申请的IU锁成IX锁
7,升级5申请的U锁成X锁  ***删除RID行,也即数据行
8,申请6(已经申请到的)RID对应的主键索引(9606db9499cf)所在page的IX锁
9,申请主键索引的key级别的X锁(9606db9499cf),***删除主键行
10,释放9申请的锁
11,释放8申请的锁
12,申请目标行索引字段col2 (fe51867f3259)所在page的IX锁
13,申请目标行索引字段col2(fe51867f3259)Key级别的X锁,***删除col2上的索引行
14,释放13申请的锁
15,释放12申请的锁
16,申请目标行索引字段(fe51867f3259)对应的Col3字段(aa0cc0efc6d9)索引所在page的IX锁
17,申请目标行索引字段(fe51867f3259)对应的Col3字段(aa0cc0efc6d9)索引Key级别的X锁,***删除col3上的索引行
阶段3
18,释放16申请的锁
19,释放17申请的锁
20,释放6申请的锁
21,释放7申请的锁
22,释放4申请的锁
23,释放5申请的锁
24~37 释放其它锁

从中可以看到,锁的申请的简化过程是,或者其规律是:
1,根据查询条件,依次申请查询字段所在Page以及字段key本身的IU/U锁,因为这个阶段是找数据(找到加IU/U),而不是直接上来就删数据,所以是IU/U锁
2,根据nocluster index 找到RID,从IU/U升级RID锁称IX/X,进行数据行的删除
3,依次删除主键索引,col2上的索引,col3上的索引,进行索引行的删除
4,依次释放加锁信息,此过程于加锁相反(先page再Key),依次释放KEY/RID和Page上的锁(先key再Page)

如果是聚集索引表,会用聚集索引Key提到RID,省略RID这一步的锁操作。

从这里可以看到,没有聚集索引的表,主键索引跟普通的非聚集索引并无二致,最终还是要使用RID来定位数据。
这里还能够得到另外一个结论:因为这里的主键索引是nonclustered的,因此该表还是数据堆表,既然是堆表,定位数据的还是RID,因此多了依次RID的锁维护动作

以上跟踪了一个最简单的delete执行过程中的加锁的步骤,其实情况可以更复杂:
1如果where条件用不到索引,
2如果where条件之一筛选出来的多行,继续用另外的条件筛选,
3如果使用聚集索引筛选,
4如果where条件筛选后仍旧有多行数据
5如果where条件无法命中任何一行
6如果采用多个非聚集索引筛选后merge结果
稍微复杂一点的情况,涉及到的锁都呈指数级增加,原本我以为很清楚sqlserver在执行delete操作的加锁过程,其实还有很多细节,没有注意到。
加解锁是一个复杂的过程,即便是单表,也会涉及不同的索引以及数据行,为此并不难理解,为什么对于单表,除了where条件不一致,为什么会出现死锁的原因。

原文地址:https://www.cnblogs.com/wy123/p/11579249.html

时间: 2024-10-07 16:12:07

追踪SQL Server执行delete操作时候锁的申请与释放过程的相关文章

SQL Server中的事务与锁

了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁:是数据库性能的重量级杀手之一,而死锁却是不同事务之间抢占数据资源造成的. 不懂的听上去,挺神奇的,懂的感觉我在扯淡,下面带你好好领略下他们的风采,嗅査下他们的狂骚.. 先说事务--概念,分类 用华仔无间道中的一句来给你诠释下:去不了终点,回到原点. 举例说明: 在一个事务中,你写啦2条sql语句,一

SQL Server 中 ROWLOCK 行级锁

一.ROWLOCK的使用 1.ROWLOCK行级锁确保,在用户取得被更新的行,到该行进行更新,这段时间内不被其它用户所修改.因而行级锁即可保证数据的一致性,又能提高数据操作的并发性. 2.ROWLOCK告诉SQL Server只使用行级锁,ROWLOCK语法可以使用在SELECT,UPDATE和DELETE语句中. 3.例如select语句中 A 连接中执行 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ begin tran select * f

引用:初探Sql Server 执行计划及Sql查询优化

原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之————探索MSSQL执行计划 作者:no_mIss 最近总想整理下对MSSQL的一些理解与感悟,却一直没有心思和时间写,晚上无事便写了一篇探索MSSQL执行计划,本文讲执行计划但不仅限于讲执行计划. 网上的SQL优化的文章实在是很多,说实在的,我也曾经到处找这样的文章,什么不要使用IN了,什么OR了,什么AND了,很多很多,还有很多人拿出仅几S甚至几MS的时

SQL Server执行计划那些事儿(2)——查找和扫描

接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混).当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下. 开门见上,直接入题 在查看执行计划时候,你是否曾经也和我一样,有这样的疑惑呢?查找和扫描究竟是什么,以及他们的在查询性能上有什么区别.下面分享下我的理解. 扫描和查找是SQL Server从表或索引中读取数据所采用的迭代器,又因为经常在执行计划中看到,因此理解他们之间的区别,对我们优化查询有很重要的

SQL Server 执行计划缓存

原文:SQL Server 执行计划缓存 标签:SQL SERVER/MSSQL SERVER/数据库/DBA/内存池/缓冲区 概述 了解执行计划对数据库性能分析很重要,其中涉及到了语句性能分析与存储,这也是写这篇文章的目的,在了解执行计划之前先要了解一些基础知识,所以文章前面会讲一些概念,学起来会比较枯燥,但是这些基础知识非常重要. 目录 概述 基础概念 怎样缓存执行计划 SQL Server自动删除执行计划 重新编译执行计划 测试 执行计划相关系统视图 手动清空缓存执行计划 测试索引更改对执

SQL Server执行计划的理解

原文:SQL Server执行计划的理解 要理解执行计划,怎么也得先理解,那各种各样的名词吧.鉴于自己还不是很了解.本文打算作为只写懂的,不懂的懂了才写. 在开头要先说明,第一次看执行计划要注意,SQL Server的执行计划是从右向左看的. 名词解析: 扫描:逐行遍历数据. 先建立一张表,并给大家看看大概是什么样子的. CREATE TABLE Person( Id int IDENTITY(1,1) NOT NULL, Name nvarchar(50) NULL, Age int NULL

SQL Server 执行计划中的扫描方式举例说明

原文地址:http://www.cnblogs.com/zihunqingxin/p/3201155.html 1.执行计划使用方式 选中需要执行的语句,点击Ctrl+L执行 2.示例student表,id,name,addressid上建立聚集索引Name建索引address无索引 3.区别1. [Table Scan]:遍历整个表,查找所有匹配的记录行.这个操作将会一行一行的检查,当然,效率也是最差的.以无索引字段为条件,按存放顺序一个个查,where address='123' 2. [I

SQL Server执行计划那些事儿(3)——书签查找

接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混).当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下. 在刚开始工作时候,总以自己有个“高科技”的工作,而感到特别神气,经常在其他人面前说一些让别人觉得高大上的措辞,到后来会在学妹面前炫耀的讲一下SQL Server的执行计划,这个时候别说执行计划了,就是SQL的优化对我来说还是个新鲜的事物,总是以自己能正确查出结果而沾沾自喜.然而,当真有不经世事的学妹

sql server 执行计划(execution plan)介绍

sql server 执行计划(execution plan)介绍 大纲:目的介绍sql server 中执行计划的大致使用,当遇到查询性能瓶颈时,可以发挥用处,而且带有比较详细的学习文档和计划,阅读者可以按照我计划进行,从而达到对执行计划一个比较系统的学习. 什么是sql server 执行计划 sql server 执行计划的大致使用 学习计划 1.什么是sql server 执行计划 执行计划是查询优化器对我们提交的T-SQL查询请求的最有效方法的的执行结果,执行计划可以告诉我们查询是如何