【问题标题】:How can I find what locks are involved in a process如何找到进程中涉及的锁
【发布时间】:2011-11-22 12:24:18
【问题描述】:

我正在运行一个包含一堆语句的 SQL 事务。

事务偶尔会导致其他进程死锁,所以我从事务中删除了一些并不重要的东西。这些现在在交易之前单独完成。

我希望能够比较更改前后 SQL 之间发生的锁定,以便我确信更改会产生影响。

我预计之前会发生更多锁定,因为事务中有更多内容。

有什么工具可以使用吗?我可以很容易地获得这两种情况的 SQL 配置文件。

我知道诸如 sp_who、sp_who2 之类的事情,但我为这些事情苦苦挣扎的是,这是某个特定时刻的快照。我想要从头到尾的全图。

【问题讨论】:

  • 试试死锁故障排除的圣经:blogs.msdn.com/b/bartd/archive/2006/09/09/… :-)
  • “所以我从事务中删除了一些并不重要的东西”-也许您应该“准确”识别导致锁定的原因...如果您的代码不是在交易中是必要的,为什么它首先存在?
  • 您使用哪个 SQL Server 版本?
  • mellamokb - 谢谢,但我已经用过了。我发现了一个僵局并理解了原因。无论如何,我已经做出改变以“消除”僵局。但我只想比较锁定,因为我不想将它投入生产,只是希望最好。
  • SQL 版本 - 2008 R2。米奇 - 不确定你的问题的相关性。 “一开始为什么会出现”,因为和其他人一样,当你第一次开发某些东西时,你不一定知道你正在做的事情的全部要求或含义。不这样想就太天真了。该软件已投入生产超过 6 个月,因此很好理解。它的扩展性很好,但需要扩展更多。

标签: sql-server


【解决方案1】:

您可以在内置过程中使用:-- sp_who2

sp_who2 还采用 SPID 的可选参数。如果传递了 spid,则 sp_who2 的结果仅显示正在执行的 SPID 的行。

您可以查看更多详细信息:master.dbo.sysprocesses 表

SELECT * FROM master.dbo.sysprocesses where spid=@1

下面的代码显示了当前命令的读取和写入,以及整个 SPID 的读取和写入次数。它还显示正在使用的协议(TCP、NamedPipes 或共享内存)。

CREATE PROCEDURE sp_who3
(
    @SessionID int = NULL
)
AS
BEGIN
SELECT
    SPID                = er.session_id
    ,Status             = ses.status
    ,[Login]            = ses.login_name
    ,Host               = ses.host_name
    ,BlkBy              = er.blocking_session_id
    ,DBName             = DB_Name(er.database_id)
    ,CommandType        = er.command
    ,SQLStatement       =
        SUBSTRING
        (
            qt.text,
            er.statement_start_offset/2,
            (CASE WHEN er.statement_end_offset = -1
                THEN LEN(CONVERT(nvarchar(MAX), qt.text)) * 2
                ELSE er.statement_end_offset
                END - er.statement_start_offset)/2
        )
    ,ObjectName         = OBJECT_SCHEMA_NAME(qt.objectid,dbid) + '.' + OBJECT_NAME(qt.objectid, qt.dbid)
    ,ElapsedMS          = er.total_elapsed_time
    ,CPUTime            = er.cpu_time
    ,IOReads            = er.logical_reads + er.reads
    ,IOWrites           = er.writes
    ,LastWaitType       = er.last_wait_type
    ,StartTime          = er.start_time
    ,Protocol           = con.net_transport
    ,transaction_isolation =
        CASE ses.transaction_isolation_level
            WHEN 0 THEN 'Unspecified'
            WHEN 1 THEN 'Read Uncommitted'
            WHEN 2 THEN 'Read Committed'
            WHEN 3 THEN 'Repeatable'
            WHEN 4 THEN 'Serializable'
            WHEN 5 THEN 'Snapshot'
        END
    ,ConnectionWrites   = con.num_writes
    ,ConnectionReads    = con.num_reads
    ,ClientAddress      = con.client_net_address
    ,Authentication     = con.auth_scheme
FROM sys.dm_exec_requests er
LEFT JOIN sys.dm_exec_sessions ses
ON ses.session_id = er.session_id
LEFT JOIN sys.dm_exec_connections con
ON con.session_id = ses.session_id
OUTER APPLY sys.dm_exec_sql_text(er.sql_handle) as qt
WHERE @SessionID IS NULL OR er.session_id = @SessionID
AND er.session_id > 50
ORDER BY
    er.blocking_session_id DESC
    ,er.session_id

END

【讨论】:

    【解决方案2】:

    您可以使用SQL Server Profiler。设置包括 Lock:Acquired 和 Lock:Released 事件的分析器跟踪。运行“之前”查询。运行您的“之后”查询。比较和对比所使用的锁(以及锁的类型)。对于上下文,您可能还希望还包括一些语句或批处理事件,以查看哪些语句导致每个锁被占用。

    【讨论】:

    • 我第一次这样做时,有一些我没有选择的隐藏列,所以我无法将锁组合在一起或理解锁所指的内容。重复...
    • 仍然无法在所有情况下很好地对锁进行分组,但大多数情况下我可以。我可以看到我在得出积极结论之前和之后的差异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    相关资源
    最近更新 更多