SQL Server 锁实验(重建索引)
昨晚某现场报一个重建索引失败的问题,远程查看后发现是自动收缩的内部会话引发的锁申请超时,突然想起来自己的加锁实验还没完成索引重建部分,今天有空正好做一下:
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 锁实验(重建索引)的更多相关文章
- SQL Server 2012 批量重建索引
关于索引的概念可以看看宋大牛的博客 T-SQL查询高级—SQL Server索引中的碎片和填充因子 整个数据库的索引很多,索引碎片多了,不可能一个个的去重建,都是重复性的工作,所以索性写了个存储过程, ...
- [S]SQL SERVER数据库维护与重建索引
第一步:查看是否需要维护,查看扫描密度/Scan Density是否为100% declare @table_id int set @table_id=object_id('表名') dbcc sho ...
- SQL Server 锁实验(SELECT加锁探究)
本例中使用begin tran和with (holdlock)提示来观察SQL Server在select语句中的锁. 开启事务是为了保证时间极短的查询也能观察到锁情况,holdlock相当于开启序列 ...
- SQL SERVER数据库维护与重建索引
第一步:查看是否需要维护,查看扫描密度/Scan Density是否为100% declare @table_id int set @table_id=object_id('表名') dbcc sho ...
- SQL Server 锁实验(INSERT加锁探究)
insert语句: 其上锁情况为: insert语句会对表上的所有索引作出更新,因此这里看到的索引列较多,我们先把所有的索引搞出来看看: 可以看到所有索引都涉及到了,然后我们来仔细分析下加锁情况: 1 ...
- SQL Server 锁实验(UPDATE加锁探究)
update语句: 本例中由于看到的是update执行完的锁情况,因此无法看到IU锁,但其实针对要修改的数据页和索引页会先加IU锁,记录和键先加U锁,然后再转化为IX和X锁. 如果想要看到IU锁和U锁 ...
- SQL Server强制使用特定索引 、并行度、锁
SQL Server强制使用特定索引 .并行度 修改或删除数据前先备份,先备份,先备份(重要事情说三遍) 很多时候你或许为了测试.或许为了规避并发给你SQL带来的一些问题,常常需要强制指定目标sql选 ...
- SQL Server锁类型
SQL Server锁类型(SQL)收藏 1. HOLDLOCK: 在该表上保持共享锁,直到整个事务结束,而不是在语句执行完立即释放所添加的锁. 2. NOLOCK:不添加共享锁和排它锁,当这个选项生 ...
- 转:sql server锁知识及锁应用
sql server锁(lock)知识及锁应用 提示:这里所摘抄的关于锁的知识有的是不同sql server版本的,对应于特定版本时会有问题. 一 关于锁的基础知识 (一). 为什么要引入锁 当多个用 ...
随机推荐
- Disruptor 为什么这么快?
为什么Disruptor不使用队列来实现RingBuffer 队列有两个指针,一个指向队头,一个指向队尾.如果有超过一个生产者想要往队列里放东西,尾指针就将成为一个冲突点,因为有多个线程要更新它. ...
- PHP中对象的本质
PHP中的面向对象 先看PHP源码中对变量的定义 #zend/zend.h typedef union_zvalue_value { long lval;/* long value */ double ...
- mysql滑动聚合
滑动聚合是按顺序对滑动窗口范围内的数据进行聚合的操作.下累积聚合不同,滑动聚合并不是统计开始计算的位置到当前位置的数据. 这里以统计最近三个月中员工第月订单情况为例来介绍滑动聚合. 滑动聚合和累积聚合 ...
- 【SqlServer系列】远程访问
1 概述 已发布[SqlServer系列]文章如下: [SqlServer系列]SQLSERVER安装教程 [SqlServer系列]数据库三大范式 [SqlServer系列]表单查询 [SqlS ...
- 安装haproxy和haproxy命令
HaProxy系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.html 1.安装haproxy CentOS自带了haproxy,但可能版本比较老. ...
- Perl语法的基本规则
因为是比较凌乱的用法规则收集,所以能看懂则看,不能看懂也无所谓.以后也会遇到. Perl脚本第一行使用#!.Perl的后缀名一般为".plx"或".pl",运行 ...
- Go基础系列:指定goroutine的执行顺序
Go channel系列: channel入门 为select设置超时时间 nil channel用法示例 双层channel用法示例 指定goroutine的执行顺序 当关闭一个channel时,会 ...
- MySQL优化(2)--------常用优化
前言 之前已经简单介绍了MySQL的优化步骤,那么接下来自然而是就是常用的SQL优化,比如inseer.group by等常用SQL的优化,会涉及SQL语句内部细节(这正是我缺乏的).最后希望自己能记 ...
- [转][Angularjs]$http.post与$.post
本文转自:https://www.cnblogs.com/wolf-sun/p/6878868.html 摘要 在angularjs发送post请求的时候,确实很困惑,在传递json数据的时候,总会遇 ...
- C# XML入门
什么是XML? XML:可扩展标记语言. XML的作用: 纯文本,兼容性强. 和HTML的区别: xml: 主要用来处理.存储数据.无规定标签,可扩展. html:对数据的显示和描述. 语法标签固定. ...