Ada*_*ler 5 sql-server-2005 sql-server deadlock delete lock-escalation
我有一个大的删除存储过程,并且在删除不会删除任何内容的情况下重现了死锁。
看起来遇到死锁的存储过程的部分是这样的(更改了表名):
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
Run Code Online (Sandbox Code Playgroud)
在我看来,尝试从这个大表中删除时,两个删除操作同时运行并且彼此死锁。对于这些项目,我知道不会有非常大的表 table1、table2、table3 的记录。
我想知道这是否可以通过更改为:
DELETE d
FROM Table1 d WITH(rowlock)
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
Run Code Online (Sandbox Code Playgroud)
我在想,由于 table1 是一个大表,sql-server 会锁定整个页面,而此提示将使其仅锁定行。请注意,我在 Table2Id、Table3Id、Table4Id 和 entityid 上对 fk 进行了索引。
我已按照此处所述启用跟踪:http : //blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx
和:
DBCC TRACEON (1222, -1)
Run Code Online (Sandbox Code Playgroud)
以下是“2011-08-29 15:46:57.78 spid15s”的日志输出切断了每一行的开头。从我看到的两个 usp_EntityFullDelete's 在同一个语句中死锁 - 一个删除行 746946 和一个删除行 628302。我对这个跟踪输出的分析是否正确?还有什么可以帮助防止这种情况发生的吗?
deadlock-list
deadlock victim=process3e9ada8
process-list
process id=processbaf048 taskpriority=0 logused=20022 waittime=3890 schedulerid=1 kpid=1304 status=suspended spid=59 sbid=0 ecid=1 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0
inputbuf
process id=processbaf588 taskpriority=0 logused=20022 waittime=3906 schedulerid=1 kpid=6244 status=suspended spid=62 sbid=0 ecid=3 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0
inputbuf
process id=process3e9a868 taskpriority=0 logused=580 waitresource=PAGE: 19:1:1942004 waittime=3890 ownerId=1135558120 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.053 XDES=0xf2512b30 lockMode=U schedulerid=3 kpid=8808 status=suspended spid=62 sbid=0 ecid=8 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0
inputbuf
process id=process3e9ada8 taskpriority=0 logused=0 waitresource=PAGE: 19:1:1928384 waittime=3765 ownerId=1135559188 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.263 XDES=0xf2512d70 lockMode=U schedulerid=3 kpid=9196 status=suspended spid=59 sbid=0 ecid=6 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0
inputbuf
process id=process3e9b198 taskpriority=0 logused=20006 waittime=3984 schedulerid=3 kpid=9212 status=suspended spid=59 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 loginname=sa isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0
inputbuf
exec dbo.usp_EntityFullDelete 746946,0
process id=process46b0da8 taskpriority=0 logused=20006 waittime=4000 schedulerid=4 kpid=6596 status=suspended spid=62 sbid=0 ecid=0 priority=0 transcount=2 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 loginname=sa isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0
inputbuf
exec dbo.usp_EntityFullDelete 628302,0
process id=process46b1048 taskpriority=0 logused=0 waitresource=PAGE: 19:1:1942003 waittime=3937 ownerId=1135559188 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.263 XDES=0xd0224ab0 lockMode=U schedulerid=4 kpid=7892 status=suspended spid=59 sbid=0 ecid=8 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:53.263 lastbatchcompleted=2011-08-29T15:46:53.263 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135559188 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300ef337933809a04fd000000000000000000000000
exec dbo.usp_EntityFullDelete 746946,0
inputbuf
process id=process46b16d8 taskpriority=0 logused=580 waitresource=PAGE: 19:1:441708 waittime=3937 ownerId=1135558120 transactionname=user_transaction lasttranstarted=2011-08-29T15:46:53.053 XDES=0xd0224870 lockMode=U schedulerid=4 kpid=6676 status=suspended spid=62 sbid=0 ecid=6 priority=0 transcount=0 lastbatchstarted=2011-08-29T15:46:45.637 lastbatchcompleted=2011-08-29T15:46:45.637 clientapp=.Net SqlClient Data Provider hostname=RGDS hostpid=9108 isolationlevel=read committed (2) xactid=1135558120 currentdb=19 lockTimeout=4294967295 clientoption1=671088672 clientoption2=128056
executionStack
frame procname=Bugfixes.dbo.usp_EntityFullDelete line=178 stmtstart=11180 stmtend=11776 sqlhandle=0x030013007b725817b4bfe400499f00000100000000000000
DELETE d
FROM Table1 d
inner join dbo.Table2 orc on orc.id = d.Table2Id
inner join dbo.Table3 orr on orr.id = orc.Table3Id
inner join Table4 oeh on oeh.id = orr.Table4Id
inner join @deleteEntities de on de.id = oeh.EntityId
frame procname=adhoc line=1 sqlhandle=0x01001300fc3e1016609402c4000000000000000000000000
exec dbo.usp_EntityFullDelete 628302,0
inputbuf
resource-list
pagelock fileid=1 pageid=1928384 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockaef9db80 mode=U associatedObjectId=72057595211284480
owner-list
owner id=process46b0da8 mode=U
waiter-list
waiter id=process3e9ada8 mode=U requestType=wait
exchangeEvent id=port80128a00 nodeId=22
owner-list
owner event=e_waitNone type=producer id=process3e9ada8
owner event=e_waitNone type=producer id=process46b1048
waiter-list
waiter event=e_waitPortClose type=consumer id=processbaf048
exchangeEvent id=port80128e20 nodeId=6
owner-list
owner event=e_waitNone type=producer id=processbaf048
waiter-list
waiter event=e_waitPortOpen type=consumer id=process3e9b198
pagelock fileid=1 pageid=1942004 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockf3d1f080 mode=U associatedObjectId=72057595211284480
owner-list
owner id=process3e9b198 mode=U
waiter-list
waiter id=process3e9a868 mode=U requestType=wait
exchangeEvent id=port80128ed0 nodeId=22
owner-list
owner event=e_waitNone type=producer id=process46b16d8
owner event=e_waitNone type=producer id=process3e9a868
waiter-list
waiter event=e_waitPortClose type=consumer id=processbaf588
exchangeEvent id=port80128320 nodeId=6
owner-list
owner event=e_waitNone type=producer id=processbaf588
waiter-list
waiter event=e_waitPortOpen type=consumer id=process46b0da8
pagelock fileid=1 pageid=1942003 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockfbcc1680 mode=U associatedObjectId=72057595211284480
owner-list
owner id=process46b0da8 mode=U
waiter-list
waiter id=process46b1048 mode=U requestType=wait
pagelock fileid=1 pageid=441708 dbid=19 objectname=Bugfixes.dbo.Table1 id=lockfc628980 mode=U associatedObjectId=72057595211284480
owner-list
owner id=process3e9b198 mode=U
waiter-list
waiter id=process46b16d8 mode=U requestType=wait
Run Code Online (Sandbox Code Playgroud)
即使指定了WITH(ROWLOCK),SQL Server 仍然可以选择将行锁升级为表锁。这可能取决于许多因素,包括:删除的行数、事务获取的总锁数以及获取的所有锁的总内存压力。
Sunil Agarwal 写了一篇很棒的文章来描述这个过程,可以在这里找到: 链接
为了减轻这些 DELETE 语句的影响,您可以做的一件事是按块执行删除:
WHILE 1 = 1
BEGIN
DELETE TOP(5000)
FROM <table>
WHERE <condition>
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END
END
Run Code Online (Sandbox Code Playgroud)
不幸的是,你原来问题的答案是一个很大的“这取决于”。
编辑(添加查询以查看锁定信息):
SELECT
DB_NAME([tl].[resource_database_id]) AS [database_name],
SCHEMA_NAME([o].[schema_id]) + '.' + [o].[name] AS [object_name],
[tl].[request_type],
[tl].[request_mode],
[tl].[request_status]
FROM sys.dm_exec_sessions AS [es]
INNER JOIN sys.dm_tran_locks AS [tl]
ON [es].[session_id] = [tl].[request_session_id]
INNER JOIN sys.objects AS [o]
ON [tl].[resource_associated_entity_id] = [o].[object_id]
WHERE [es].[is_user_process] = 1;
Run Code Online (Sandbox Code Playgroud)
我希望这个“几乎回答”有帮助,
马特