为何SQL Server的SET DEADLOCK_PRIORITY HIGH未被生效?
问题分析与解决方案
这绝对是个让人头疼的问题——明明给重要业务进程设置了高死锁优先级,结果它反而被选为死锁牺牲品,而SSMS智能提示这类低优先级进程却存活了。结合你提供的信息,这其实是SQL Server 2012的一个已知bug,下面给你详细拆解:
1. 为什么DEADLOCK_PRIORITY看似失效?
问题的核心原因很明确:你的SQL Server 2012启用了锁分区(Lock Partitioning),且版本早于CU6(KB2776344补丁)。在这个版本区间内,锁分区会破坏死锁优先级的判断逻辑,导致SQL Server完全忽略优先级设置,甚至出现“优先级越高越容易被牺牲”的反向行为,这就是你遇到的异常情况。
2. 关于taskpriority="10"的疑惑
你提到MSDN显示HIGH对应死锁优先级值为5,但死锁图里显示的是10——这也是这个bug的典型表现。当启用锁分区时,SQL Server内部会错误地将死锁优先级数值翻倍,所以你设置的HIGH(对应值5)就被显示成了10。注意看死锁图里的<process>节点,它同时有priority="5"(这才是你设置的正确值)和taskpriority="10"(被bug篡改后的数值),这是判断该bug的关键线索。
3. 解决办法
要彻底解决这个问题,有两个可行途径:
- 优先推荐:安装SQL Server 2012 CU6及以上补丁:KB2776344专门修复了锁分区场景下死锁优先级判断错误的问题,安装后死锁选择逻辑会恢复正常。
- 临时 workaround:禁用锁分区:如果你暂时无法安装补丁,可以通过跟踪标记1236禁用锁分区,但这可能会影响高并发场景下的锁性能,需要谨慎评估后再操作。
补充:死锁图验证
你提供的清理后死锁图也明确验证了这个bug的存在:
<deadlock> <victim-list> <victimProcess id="process5f390c8" /> </victim-list> <process-list> <process id="process5f390c8" taskpriority="10" logused="3200" waitresource="KEY: 6:281474978938880 (655334c51469)" waittime="1806" ownerId="296690694" transactionname="ALTER PARTITION FUNCTION" lasttranstarted="2018-01-29T11:59:36.140" XDES="0x886312d28" lockMode="X" schedulerid="9" kpid="32684" status="suspended" spid="86" sbid="0" ecid="0" priority="5" trancount="1" lastbatchstarted="2018-01-29T11:58:38.310" lastbatchcompleted="2018-01-29T11:58:38.310" lastattention="1900-01-01T00:00:00.310" clientapp="CLIENTAPP" hostname="HOSTNAME" hostpid="10912" loginname="DOMAIN\\USERNAME" isolationlevel="read committed (2)" xactid="296690694" currentdb="6" lockTimeout="4294967295" clientoption1="673187936" clientoption2="128056"> <executionStack> <frame procname="adhoc" line="2" stmtstart="138" sqlhandle="0x01000600a1f28605207939860500000000000000000000000000000000000000000000000000000000000000"> ...removed...</frame> <frame procname="mssqlsystemresource.sys.sp_executesql" line="1" stmtstart="-1" sqlhandle="0x0400ff7f427f99d90100000000000000000000000000000000000000000000000000000000000000000000000"> ...removed...</frame> <frame procname="SUBSPNAME" line="75" stmtstart="5434" stmtend="5502" sqlhandle="0x0300060011b27f3d08e76c012ba8000001000000000000000000000000000000000000000000000000000000"> ...removed...</frame> <frame procname="SPNAME" line="65" stmtstart="4234" stmtend="4516" sqlhandle="0x030006004990de353efaf70071a8000001000000000000000000000000000000000000000000000000000000"> ...removed...</frame> <frame procname="adhoc" line="1" sqlhandle="0x01000600679e2e28907739860500000000000000000000000000000000000000000000000000000000000000"> ...removed...</frame> </executionStack> <inputbuf> ...removed...</inputbuf> </process> <process id="process791872558" taskpriority="0" logused="0" waitresource="OBJECT: 6:139251651:11 " waittime="8299" ownerId="300839454" transactionname="MDView" lasttranstarted="2018-01-29T12:19:33.727" XDES="0x4cddd58a0" lockMode="Sch-S" schedulerid="9" kpid="20372" status="suspended" spid="75" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2018-01-29T12:19:33.720" lastbatchcompleted="2018-01-29T12:19:33.713" lastattention="2018-01-29T12:19:18.360" clientapp="Microsoft SQL Server Management Studio" hostname="ANOTHERHOSTNAME" hostpid="62236" loginname="DOMAIN\\ANOTHERUSERNAME" isolationlevel="read committed (2)" xactid="300839326" currentdb="6" lockTimeout="10000" clientoption1="671090784" clientoption2="128056"> <executionStack> <frame procname="adhoc" line="1" stmtstart="56" sqlhandle="0x02000000c7bca00d097183e2d5dd8e6785f452180936fd930000000000000000000000000000000000000000"> ...removed...</frame> <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"> ...removed...</frame> </executionStack> <inputbuf> ...removed...</inputbuf> </process> </process-list> <resource-list> <keylock hobtid="281474978938880" dbid="6" objectname="DBNAME.sys.sysschobjs" indexname="clst" id="lock1ef508c700" mode="U" associatedObjectId="281474978938880"> <owner-list> <owner id="process791872558" mode="S" /> </owner-list> <waiter-list> <waiter id="process5f390c8" mode="X" requestType="convert" /> </waiter-list> </keylock> <objectlock lockPartition="11" objid="139251651" subresource="FULL" dbid="6" objectname="TABLENAME" id="lock398e43e00" mode="Sch-M" associatedObjectId="139251651"> <owner-list> <owner id="process5f390c8" mode="Sch-M" /> </owner-list> <waiter-list> <waiter id="process791872558" mode="Sch-S" requestType="wait" /> </waiter-list> </objectlock> </resource-list> </deadlock>
内容的提问来源于stack exchange,提问作者Rhys Jones




