昨晚某现场报一个重建索引失败的问题,远程查看后发现是自动收缩的内部会话引发的锁申请超时,突然想起来自己的加锁实验还没完成索引重建部分,今天有空正好做一下:

USE [数据库名]
GO
ALTER INDEX <索引名> ON dbo.<表名> REBUILD PARTITION = ALL WITH ( MAXDOP = 4, ONLINE = OFF, SORT_IN_TEMPDB = OFF )
GO

先试了下聚集索引的重建,以下是相关会话的所有加锁情况:

从以上的锁分布情况来分析,首先我们过滤掉所有非相关表的锁,那么整个结果集只剩下了6行:

55	    5	    1589580701	0	    TAB	        S	    GRANT
55 5 1589580701 0 TAB S GRANT
55 5 1589580701 0 TAB S GRANT
55 5 1589580701 0 TAB S GRANT
55 5 1589580701 0 TAB Sch-M GRANT
55 5 1605580758 0 TAB Sch-M GRANT

这里出现了4个TAB类型的S锁和一个表级的Sch-M锁以及一个聚集索引的Sch-M锁,从官网提供的锁兼容图来看S锁和Sch-M锁是不兼容的,因此这几个S锁的出现就比较诡异了,查看dm_tran_locks发现request_exec_context_id不一样,而官网对此字段的解释就一句:Execution context ID of the process that currently owns this request.

所以这里有一个问题:不同的request_exec_context_id代表的TAB类型的S锁到底是什么?为何与Sch-M锁不冲突?

在SQLOS的任务调度算法中,有一个概念叫做context switch,同计算机原理中的CPU切换一样,意思是同一个CPU针对并发的会话进行线程切换。我们这里只有一个会话一条语句,因此猜测是并行造成的现象。

事后进行了多次测试,发现开不同的并行数(MAXDOP)目得到的S锁数目与并行数一样,因此这里得request_exec_context_id每个值对应一个并行线程。而针对同一个资源S锁和Sch-M是不兼容的,因此感觉这里的S锁是一个显示小BUG。

Ps:下图里的object_id与之前的不同是因为不是一个表,无需在意。

因此重建聚集索引的过程中会对表和涉及的索引加Sch-M的架构锁,而此架构锁与所有其他锁冲突,因此不能再执行任何针对此表的增删改查。

之后测试了非聚集索引的情况,加锁情况一致因此不作讨论。

SQL Server 锁实验(重建索引)的更多相关文章

  1. SQL Server 2012 批量重建索引

    关于索引的概念可以看看宋大牛的博客 T-SQL查询高级—SQL Server索引中的碎片和填充因子 整个数据库的索引很多,索引碎片多了,不可能一个个的去重建,都是重复性的工作,所以索性写了个存储过程, ...

  2. [S]SQL SERVER数据库维护与重建索引

    第一步:查看是否需要维护,查看扫描密度/Scan Density是否为100% declare @table_id int set @table_id=object_id('表名') dbcc sho ...

  3. SQL Server 锁实验(SELECT加锁探究)

    本例中使用begin tran和with (holdlock)提示来观察SQL Server在select语句中的锁. 开启事务是为了保证时间极短的查询也能观察到锁情况,holdlock相当于开启序列 ...

  4. SQL SERVER数据库维护与重建索引

    第一步:查看是否需要维护,查看扫描密度/Scan Density是否为100% declare @table_id int set @table_id=object_id('表名') dbcc sho ...

  5. SQL Server 锁实验(INSERT加锁探究)

    insert语句: 其上锁情况为: insert语句会对表上的所有索引作出更新,因此这里看到的索引列较多,我们先把所有的索引搞出来看看: 可以看到所有索引都涉及到了,然后我们来仔细分析下加锁情况: 1 ...

  6. SQL Server 锁实验(UPDATE加锁探究)

    update语句: 本例中由于看到的是update执行完的锁情况,因此无法看到IU锁,但其实针对要修改的数据页和索引页会先加IU锁,记录和键先加U锁,然后再转化为IX和X锁. 如果想要看到IU锁和U锁 ...

  7. SQL Server强制使用特定索引 、并行度、锁

    SQL Server强制使用特定索引 .并行度 修改或删除数据前先备份,先备份,先备份(重要事情说三遍) 很多时候你或许为了测试.或许为了规避并发给你SQL带来的一些问题,常常需要强制指定目标sql选 ...

  8. SQL Server锁类型

    SQL Server锁类型(SQL)收藏 1. HOLDLOCK: 在该表上保持共享锁,直到整个事务结束,而不是在语句执行完立即释放所添加的锁. 2. NOLOCK:不添加共享锁和排它锁,当这个选项生 ...

  9. 转:sql server锁知识及锁应用

    sql server锁(lock)知识及锁应用 提示:这里所摘抄的关于锁的知识有的是不同sql server版本的,对应于特定版本时会有问题. 一 关于锁的基础知识 (一). 为什么要引入锁 当多个用 ...

随机推荐

  1. Http协议中get和post的区别

    get(默认值)是通过URL传递表单值,数据追加在action属性后面. post传递的表单值是隐藏到http报文体中,url中看不到. get是通过url传递表单值,post通过url看不到表单域的 ...

  2. Java设计模式学习记录-观察者模式

    前言 观察者模式也是对象行为模式的一种,又叫做发表-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式. 咱们目前用的最多的就是各种MQ(Message Queue ...

  3. 第12章 Linux配置定时任务详解

    12.1 配置定时任务 首先需弄清的概念: (1).crond是一个daemon类程序,路径为/usr/sbin/crond.默认会以后台方式启动,service或systemd方式启动crond默认 ...

  4. Perl的浅拷贝和深度拷贝

    首先是深.浅拷贝的概念: 浅拷贝:shallow copy,只拷贝第一层的数据.Perl中赋值操作就是浅拷贝 深拷贝:deep copy,递归拷贝所有层次的数据,Perl中Clone模块的clone方 ...

  5. 使用Dev C++调试(debug)程序

    在 "Tools" -> "Compiler Options" -> "Add following commands when calli ...

  6. 【原】KMeans与深度学习自编码AutoEncoder结合提高聚类效果

    这几天在做用户画像,特征是用户的消费商品的消费金额,原始数据(部分)是这样的: id goods_name goods_amount 男士手袋 1882.0 淑女装 2491.0 女士手袋 345.0 ...

  7. python的一些内置模块

    整理了几种python的常用内置模块. 内置函数思维导图:https://www.processon.com/view/link/5c7902b1e4b0168e4200846a re模块 re(re ...

  8. 第一册:lesson sixty one.

    原文: A bad cold. A:Where is Jim? B:He is in bed. A:What's the matter with him? B:He fells ill. A:He l ...

  9. sql server查询语句条件判断字段值是否为NULL

    判断字段是否为null select * from table where c is null    select * from table where c is not null 判断字段是否为空 ...

  10. mysql中union 查询

    UNION ALL只是简单的将两个结果合并后就返回.这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了. 从效率上说,UNION ALL 要比UNION快很多,所以,如果可 ...