6 sql-server deadlock merge-replication
我在某些合并复制数据库的 msmerge_contents 表上遇到了一个非常令人困惑的问题。似乎我在表 msmerge_contents 的同一索引上的完全相同的行上收到了死锁。
这是我目前看到的死锁 xml。根据我可以告诉索引名称的信息:1 表示聚集索引(查看关联的 objid)。所以它是相同的 i/o 路径并且行 hashid 是相同的 (b5f70c321dc6),即同一行。一个过程是我相信合并代理运行的 msmakegeneration(在这种情况下每分钟),另一个过程是调用的触发器(每次请求表更新时)。任何人都可以对这个问题有所了解,我仍在学习僵局,对我来说这没有意义。谢谢
<deadlock-list>
<deadlock victim="process8f31f9498">
<process-list>
<process id="process8f31f9498" taskpriority="5" logused="2616" waitresource="KEY: 20:72057594653704192 (b5f70c321dc6)" waittime="1925" ownerId="3680081779" transactionname="user_transaction" lasttranstarted="2012-10-05T10:02:01.223" XDES="0x8f3b283a8" lockMode="U" schedulerid="7" kpid="11784" status="suspended" spid="252" sbid="0" ecid="0" priority="-5" trancount="2" lastbatchstarted="2012-10-05T10:02:01.177" lastbatchcompleted="2012-10-05T10:02:01.177" lastattention="1900-01-01T00:00:00.177" clientapp="GN-SQL-GW_National-GW_National Publicati-vz-sql-59" hostname="GN-SQL" hostpid="19364" loginname="DCSINFOSYS\SQLServer" isolationlevel="read committed (2)" xactid="3680081779" currentdb="20" lockTimeout="4294967295" clientoption1="673384544" clientoption2="128024">
<executionStack>
<frame procname="mssqlsystemresource.sys.sp_MSmakegeneration" line="337" stmtstart="29568" stmtend="29880" sqlhandle="0x0300ff7fa885d0f97c6e5901f39f000001000000000000000000000000000000000000000000000000000000">
update dbo.MSmerge_contents with (rowlock) set generation = @target_gen
where generation = @gen and tablenick = @art_nick </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 32767 Object Id = -103774808] </inputbuf>
</process>
<process id="process87f1e4188" taskpriority="0" logused="676" waitresource="KEY: 20:72057594653704192 (b5f70c321dc6)" waittime="1994" ownerId="3680083804" transactionname="UPDATE" lasttranstarted="2012-10-05T10:02:01.363" XDES="0x38b50b6a8" lockMode="X" schedulerid="3" kpid="3920" status="suspended" spid="93" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2012-10-05T10:02:01.210" lastbatchcompleted="2012-10-05T10:02:01.210" lastattention="1900-01-01T00:00:00.210" clientapp="National KBM R1 Gateway" hostname="HQ-GATEWAY" hostpid="9592" loginname="DCSINFOSYS\GatewayBot" isolationlevel="read committed (2)" xactid="3680083804" currentdb="20" lockTimeout="4294967295" clientoption1="673319008" clientoption2="128056">
<executionStack>
<frame procname="GW_National.dbo.MSmerge_upd_A5AC5485C2484F3C9BFC2CE7057DE6B4" line="97" stmtstart="8470" stmtend="9582" sqlhandle="0x03001400d6e21f3c4265d200d5a0000000000000000000000000000000000000000000000000000000000000">
update MSmerge_ctsv_A5AC5485C2484F3C9BFC2CE7057DE6B4 with (rowlock)
set lineage = { fn UPDATELINEAGE(lineage, @replnick, @oldmaxversion+1) },
generation = @newgen,
partchangegen = case when (@partchange = 1 or @joinchange = 1) then @newgen else partchangegen end,
colv1 = NULL
FROM inserted as I JOIN MSmerge_ctsv_A5AC5485C2484F3C9BFC2CE7057DE6B4 as V with (rowlock)
ON (I.rowguidcol=V.rowguid)
and V.tablenick = @tablenick
option (force order, loop join) </frame>
<frame procname="GW_National.http.StoreTransaction" line="66" stmtstart="3658" stmtend="3968" sqlhandle="0x03001400f6be377e130a2c019c9e000001000000000000000000000000000000000000000000000000000000">
UPDATE
Requests
SET
StatusMessage = @StatusMessage,
GatewayVersion = @GatewayVersion
WHERE
SubTransactionUUID = @GatewayTransactionGuid </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 20 Object Id = 2117582582] </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594653704192" dbid="20" objectname="GW_National.dbo.MSmerge_contents" indexname="1" id="lock888cc6e00" mode="U" associatedObjectId="72057594653704192">
<owner-list>
<owner id="process87f1e4188" mode="U"/>
<owner id="process87f1e4188" mode="X" requestType="convert"/>
</owner-list>
<waiter-list>
<waiter id="process8f31f9498" mode="U" requestType="convert"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594653704192" dbid="20" objectname="GW_National.dbo.MSmerge_contents" indexname="1" id="lock888cc6e00" mode="U" associatedObjectId="72057594653704192">
<owner-list>
<owner id="process8f31f9498" mode="S"/>
<owner id="process8f31f9498" mode="U" requestType="convert"/>
</owner-list>
<waiter-list>
<waiter id="process87f1e4188" mode="X" requestType="convert"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
Run Code Online (Sandbox Code Playgroud)
这个锁兼容性矩阵可以提供一些线索。请注意,如果授予模式为S(共享读),则请求U(可更新)的事务将被授予访问权限。另请注意,其他方式也是如此,即 U 是现有锁并且对 S 的请求被授予。X(独占访问)既不兼容也不S兼容U。也不U兼容U
IE
Existing Requested Status
S U Yes
U S Yes
U U No
S X No
U X No
Run Code Online (Sandbox Code Playgroud)
在两个不同的交易中,首先获取同一资源上的 S 或 U。然后一段时间后,他们希望将当前锁转换为更具排它性的锁。这是可能导致上述死锁的一种可能的顺序。
T1 : Request S
SQL : Granted.
T2 : Request U
SQL : Granted (because U is compatible with S)
T1 : Convert from S to U. (lock escalation)
SQL : Wait. T2 is holding U.
T2 : Convert from U to X (lock escalation)
SQL : Wait. T1 is holding S. (DEADLOCK!!)
Run Code Online (Sandbox Code Playgroud)
要解决此死锁,请不要进行锁转换。首先尝试获得最多的独占锁。即T1应该直接去U而T2应该去X
在你的情况下
<owner id="process8f31f9498" mode="S"/>
<owner id="process8f31f9498" mode="U" requestType="convert"/>
Run Code Online (Sandbox Code Playgroud)
然而
<owner id="process87f1e4188" mode="U"/>
<owner id="process87f1e4188" mode="X" requestType="convert"/>
Run Code Online (Sandbox Code Playgroud)
如果您有任何疑问,请告诉我。
| 归档时间: |
|
| 查看次数: |
2017 次 |
| 最近记录: |