SQL Server 2008死锁图executionStack有多完整?
当我在SQL Server中得到死锁图xml时,它会为每个进程显示一个executionStack,例如(我删除了大部分属性):
<process>
<executionStack>
<frame>INSERT INTO MYTABLE</frame>
<frame>INSERT INTO MYTABLE</frame>
</executionStack>
<inputbuf>INSERT INTO MYTABLE</inputbuf>
</process>
我知道框架列表不包含事务中的所有框架,但是它包含了所有与死锁有关的框架,所以我不需要再进一步观察? 或者我是否还需要在同一个事务中检查前面的sql语句以获得有关死锁原因的完整图片?
编辑:进一步澄清,如果在两个单独的spid中运行,以下内容可能会自我死锁:
select * from mytable where column = @arg从mytable中删除where column = @arg
死锁图表会显示select语句以及delete语句,还是仅显示delete语句,因为这是事务中的最后一个语句? 在没有看到select语句的情况下,很难确定正确的修复(例如,select中的updlock提示)。
你需要在同一个事务中检查前面的sql语句。
死锁图表只显示了死锁发生时执行的语句的调用栈。 实际获得死锁资源的声明可能不存在。 这很容易演示如下。
连接1
CREATE TABLE T1
(
id INT PRIMARY KEY,
foo CHAR(100),
bar CHAR(100)
)
INSERT INTO T1
(id)
VALUES (1),
(2)
GO
BEGIN TRAN
UPDATE T1
SET foo = '123'
WHERE id = 1
WAITFOR DELAY '00:00:05'
GO
UPDATE T1
SET bar = 'dlock'
WHERE id = 2
ROLLBACK
DROP TABLE T1
连接2(连接1后快速执行)
BEGIN TRAN
UPDATE T1
SET foo = '123'
WHERE id = 2
WAITFOR DELAY '00:00:05'
GO
UPDATE T1
SET bar = 'dlock'
WHERE id = 1
ROLLBACK
死锁图
<process-list>
<process
id="process520d1c8"
taskpriority="0"
logused="504"
waitresource="KEY: 1:72057594051100672 (010086470766)"
waittime="3666"
ownerId="10399789"
transactionname="user_transaction"
lasttranstarted="2011-10-30T13:45:29.030"
XDES="0x4eb5be8"
lockMode="X"
schedulerid="2"
kpid="8656"
status="suspended"
spid="59"
sbid="0"
ecid="0"
priority="0"
trancount="2"
lastbatchstarted="2011-10-30T13:45:34.047"
lastbatchcompleted="2011-10-30T13:45:34.043"
clientapp="Microsoft SQL Server Management Studio - Query"
hostname="MyPC"
hostpid="7544"
loginname="Me"
isolationlevel="read committed (2)"
xactid="10399789"
currentdb="1"
lockTimeout="4294967295"
clientoption1="671090784"
clientoption2="390200">
<executionStack>
<frame
procname="adhoc"
line="2"
stmtstart="58"
sqlhandle="0x02000000b24eb7001f552b64e5c2bf2ccb1f2acfda154410">
UPDATE [T1] set [bar] = @1 WHERE [id]=@2
</frame>
<frame
procname="adhoc"
line="2"
stmtstart="4"
stmtend="90"
sqlhandle="0x020000002688730e96c94af4582dfb097fa79a39ea620d63">
UPDATE T1 SET bar = 'dlock' where id=1
</frame>
</executionStack>
<inputbuf>
UPDATE T1 SET bar = 'dlock' where id=1
rollback
</inputbuf>
</process>
<process
id="process370d8718"
taskpriority="0"
logused="504"
waitresource="KEY: 1:72057594051100672 (020068e8b274)"
waittime="5579"
ownerId="10399738"
transactionname="user_transaction"
lasttranstarted="2011-10-30T13:45:27.040"
XDES="0x1ef7ac10"
lockMode="X"
schedulerid="1"
kpid="2060"
status="suspended"
spid="52"
sbid="0"
ecid="0"
priority="0"
trancount="2"
lastbatchstarted="2011-10-30T13:45:32.083"
lastbatchcompleted="2011-10-30T13:45:32.043"
clientapp="Microsoft SQL Server Management Studio - Query"
hostname="MyPC"
hostpid="7544"
loginname="Me"
isolationlevel="read committed (2)"
xactid="10399738"
currentdb="1"
lockTimeout="4294967295"
clientoption1="671098976"
clientoption2="390200">
<executionStack>
<frame
procname="adhoc"
line="3"
stmtstart="58"
sqlhandle="0x02000000b24eb7001f552b64e5c2bf2ccb1f2acfda154410">
UPDATE [T1] set [bar] = @1 WHERE [id]=@2
</frame>
<frame
procname="adhoc"
line="3"
stmtstart="8"
stmtend="94"
sqlhandle="0x020000004a869b267636c00306e481791dec78ade36b3f39">
UPDATE T1 SET bar = 'dlock' where id=2
</frame>
</executionStack>
<inputbuf>
UPDATE T1 SET bar = 'dlock' where id=2
ROLLBACK
DROP TABLE T1
</inputbuf>
</process>
</process-list>
没有显示首先获得锁的列foo
的分配。
(注意:如果没有GO
语句将语句分成不同的批次,那么在这种情况下您会看到违规的语句,但通常锁的获取可能发生在调用堆栈的更下方,因此实际获取锁的语句仍然不会显示)
上一篇: How complete is the SQL Server 2008 deadlock graph executionStack?