SQL Server 2014如何提升非在线的在线操作
作者:网络转载 发布时间:[ 2015/7/7 13:54:56 ] 推荐标签:数据库
当你查看DMV sys.dm_tran_locks时,你会看到那个需要共享锁(Shared Lock(S))的会话需要等待。这个会话会永远等待。我刚才说过:“部分在线”……
1 SELECT * FROM sys.dm_tran_locks

当我们执行带有锁优先级(Lock Priority)的在线索引重建时,有趣的事情发生了:
1 -- Perform an Online Index Rebuild
2 ALTER INDEX idx_Col1 ON Foo REBUILD
3 WITH
4 (
5 ONLINE = ON
6 (
7 WAIT_AT_LOW_PRIORITY
8 (
9 MAX_DURATION = 1,
10 ABORT_AFTER_WAIT = SELF
11 )
12 )
13 )
14 GO

在这个情况下,我们的ALTER INDEX语句会等待1分钟(MAX_DURATION),然后语句本身取消了(ABORT_AFTER_WAIT)。
如果你在这里指定了BLOCKERS选项,那么阻塞的会话会回滚。当我们同时(在1分钟期间)查看DMV sys.dm_tran_locks,我们看到了有趣的东西:

从图中可以看到,SQL Server这里请求一个LOW_PRIORITY_WAIT的状态。因此3个请求状态(GRANT,WAIT,CONVERT)有了第4个选项:LOW_PRIORITY_WAIT。当我们查看DMV sys.dm_os_waiting_tasks时,事情变得有意思(59是执行语句的会话ID):

1 SELECT * FROM sys.dm_os_waiting_tasks WHERE session_id='59'
在线索引重建操作的等待会话报告了一个新的等待类型LCK_M_S_LOW_PRIORITY。这意味着当在线索引重建操作被阻塞时,我们可以从服务器级别(sys.dm_os_wait_stats)的等待统计信息里获得——不错!
但是LCK_M_S_LOW_PRIORITY并不是新的等待类型。在SQL Server 2014里,当你查看DMV sys.dm_os_wait_stats时,会看到21个新的等待类型:
1 SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE '%LOW_PRIORITY%'
LCK_M_SCH_S_LOW_PRIORITY
LCK_M_SCH_M_LOW_PRIORITY
LCK_M_S_LOW_PRIORITY
LCK_M_U_LOW_PRIORITY
LCK_M_X_LOW_PRIORITY
LCK_M_IS_LOW_PRIORITY
LCK_M_IU_LOW_PRIORITY
LCK_M_IX_LOW_PRIORITY
LCK_M_SIU_LOW_PRIORITY
LCK_M_SIX_LOW_PRIORITY
LCK_M_UIX_LOW_PRIORITY
LCK_M_BU_LOW_PRIORITY
LCK_M_RS_S_LOW_PRIORITY
LCK_M_RS_U_LOW_PRIORITY
LCK_M_RIn_NL_LOW_PRIORITY
LCK_M_RIn_S_LOW_PRIORITY
LCK_M_RIn_U_LOW_PRIORITY
LCK_M_RIn_X_LOW_PRIORITY
LCK_M_RX_S_LOW_PRIORITY
LCK_M_RX_U_LOW_PRIORITY
LCK_M_RX_X_LOW_PRIORITY
所有主要的等待类型(LCK_M_*)都有额外的锁优先级等待类型。这个非常酷,也非常强大,因为你很容易从中可以跟踪到为什么在线重建索引操作被阻塞。另外,对于分区切换(Partition Switching)也适用同样的技术(锁优先级(Lock Priorities)),因为在切换期间,操作也要在2个表(原表,目标表)上获取架构修改锁(Schema Modification Lock (Sch-M))。
我希望这篇文章可以让你理解SQL Server 2014里的锁优先级(Lock Priorities),还有为什么SQL Server里的“在线”操作实际上只是“部分在线”。

sales@spasvo.com