zoukankan      html  css  js  c++  java
  • 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的架构锁,而此架构锁与所有其他锁冲突,因此不能再执行任何针对此表的增删改查。

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

  • 相关阅读:
    今天面试一些程序员(新,老)手的体会
    UVA 10635 Prince and Princess
    poj 2240 Arbitrage
    poj 2253 Frogger
    poj 2485 Highways
    UVA 11258 String Partition
    UVA 11151 Longest Palindrome
    poj 1125 Stockbroker Grapevine
    poj 1789 Truck History
    poj 3259 Wormholes
  • 原文地址:https://www.cnblogs.com/leohahah/p/7201658.html
Copyright © 2011-2022 走看看