【问题标题】:How complete is the SQL Server 2008 deadlock graph executionStack?SQL Server 2008死锁图executionStack有多完善?
【发布时间】:2011-05-26 08:23:04
【问题描述】:

当我在 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 中删除 column = @arg

死锁图会显示 select 语句以及 delete 语句,还是只显示 delete 语句,因为那是事务中的最后一条语句?如果也没有看到 select 语句,就很难确定正确的修复(例如,选择上的更新锁定提示)。

【问题讨论】:

  • 如何完成?它应该包含诊断原因所需的所有信息......

标签: sql-server sql-server-2008 deadlock


【解决方案1】:

你需要在同一个事务中检查前面的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 语句来使语句分开批处理,在这种情况下,您会看到有问题的语句,但通常锁获取可能发生在调用堆栈的更下方,因此实际获取锁的语句仍然不会'不显示)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多