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

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. java发送http get请求的两种方式

    长话短说,废话不说 一.第一种方式,通过HttpClient方式,代码如下: public static String httpGet(String url, String charset) thro ...

  2. Docker 构建映像

    .用docker commit构建映像 .docker run -i -t centos /bin/bash //启动一个容器,启动后默认进入该窗口的bash进程 .yum install -y ep ...

  3. 谈谈 JAVA 的对象序列化

    所谓的『JAVA 对象序列化』就是指,将一个 JAVA 对象所描述的所有内容以文件 IO 的方式写入二进制文件的一个过程.关于序列化,主要涉及两个流,ObjectInputStream 和 Objec ...

  4. SpringBoot快速引入第三方jar包

    工作中,我们常会用到第三方jar包,而这些jar包往往在maven仓库是搜不到的,下面推荐一种简单.快速的引入第三方依赖的方法: 比如第三方jar包在lib文件夹下,对pom.xml的配置如下: &l ...

  5. Go基础系列:简单数据类型

    每一个变量都有数据类型,Go中的数据类型有: 简单数据类型:int.float.complex.bool和string 数据结构或组合(composite):struct.array.slice.ma ...

  6. Yum搭建LNMP环境(动、静、库分离)(week4_day5)--技术流ken

    前言 本篇博客使用yum来搭建lnmp环境,将采用动态,静态以及数据库分开安装的方式即nginx,php,mysql.会被分开安装在不同的服务器之上,搭建出来一套lnmp环境,并部署wordpress ...

  7. Host '127.0.0.1' is not allowed to connect to this MySQL server

    错误:Host  '127.0.0.1'  is  not  allowed  to  connect  to  this  MySQL  server 一般原因: MySQL数据库的配置文件my.i ...

  8. CLR 协变、逆变

    看书看得有点晕了,协变.逆变傻傻分不清楚. 看到泛型和委托.委托方法,发现这里面的协变和逆变不一样. 泛型的逆变和协变:如果某个返回类型可以由其基类替换,那么这个类型就是支持协变的.如果某个参数类型可 ...

  9. 从零开始学安全(十一)●IP地址

    127 都是本机地址 ip  DE 类网段 都是广播网段 它并不指向特定的网络 用不上

  10. double在输出为字符串的几种方法效率测试

    测试结果: double->none 366msdouble->long 161msdouble->long2 188msdouble->format 564msdouble- ...