AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 117599
Accepted
Collin Dauphinee
Collin Dauphinee
Asked: 2015-10-10 12:39:48 +0800 CST2015-10-10 12:39:48 +0800 CST 2015-10-10 12:39:48 +0800 CST

在没有分析器的情况下,如何查看查询等待锁定的时间?

  • 772

我正在尝试诊断间歇性花费很长时间的查询。我怀疑它可能在尝试获取锁时被阻止。我无权在遇到问题的环境中使用探查器。

有没有办法让我在不使用外部分析器的情况下获得有关此单个查询被阻止多长时间的统计信息?

sql-server sql-server-2014
  • 1 1 个回答
  • 1094 Views

1 个回答

  • Voted
  1. Best Answer
    Kin Shah
    2015-10-10T12:54:32+08:002015-10-10T12:54:32+08:00

    (如果您有权访问 DMV,然后使用 调查sp_whoisactive 。@find_block_leaders = 1只需告诉您 DBA(如果您不是)部署它并授予您执行权限。)

    SQL 服务器动态管理视图是您最好的朋友:

    以下是找出阻塞的几种方法:

    --Ref: https://sqlserverperformance.wordpress.com/category/diagnostic-queries/
    select t1.resource_type as 'lock type'
        ,db_name(resource_database_id) as 'database'
        ,t1.resource_associated_entity_id as 'blk object'
        ,t1.request_mode as 'lock req'
        ,--- lock requested
        t1.request_session_id as 'waiter sid'
        ,t2.wait_duration_ms as 'wait time'
        ,-- spid of waiter  
        (
            select [text]
            from sys.dm_exec_requests as r -- get sql for waiter
            cross apply sys.dm_exec_sql_text(r.sql_handle)
            where r.session_id = t1.request_session_id
            ) as 'waiter_batch'
        ,(
            select substring(qt.text, r.statement_start_offset / 2, (
                        case 
                            when r.statement_end_offset = - 1
                                then LEN(CONVERT(nvarchar(max), qt.text)) * 2
                            else r.statement_end_offset
                            end - r.statement_start_offset
                        ) / 2)
            from sys.dm_exec_requests as r
            cross apply sys.dm_exec_sql_text(r.sql_handle) as qt
            where r.session_id = t1.request_session_id
            ) as 'waiter_stmt'
        ,-- statement blocked
        t2.blocking_session_id as 'blocker sid'
        ,-- spid of blocker
        (
            select [text]
            from sys.sysprocesses as p -- get sql for blocker
            cross apply sys.dm_exec_sql_text(p.sql_handle)
            where p.spid = t2.blocking_session_id
            ) as 'blocker_stmt'
    from sys.dm_tran_locks as t1
    inner join sys.dm_os_waiting_tasks as t2 on t1.lock_owner_address = t2.resource_address;
    

    更深入地了解阻塞:

    -- Pedro Lopes (Microsoft) [email protected] (http://blogs.msdn.com/b/blogdoezequiel/)
    -- Waiter and Blocking Report
    SELECT -- blocked
        er.session_id AS blocked_spid
        ,ot.task_state AS [status]
        ,owt.wait_type AS blocked_spid_wait_type
        ,owt.wait_duration_ms AS blocked_spid_wait_time_ms
        ,
        -- Check sys.dm_os_waiting_tasks for Exchange wait types in http://technet.microsoft.com/en-us/library/ms188743.aspx.
        -- Wait Resource e_waitPipeNewRow in CXPACKET waits – Producer waiting on consumer for a packet to fill.
        -- Wait Resource e_waitPipeGetRow in CXPACKET waits – Consumer waiting on producer to fill a packet.
        owt.resource_description AS blocked_spid_res_desc
        ,CASE 
            WHEN owt.pageid = 1
                OR owt.pageid % 8088 = 0
                THEN 'Is_PFS_Page'
            WHEN owt.pageid = 2
                OR owt.pageid % 511232 = 0
                THEN 'Is_GAM_Page'
            WHEN owt.pageid = 3
                OR (owt.pageid - 1) % 511232 = 0
                THEN 'Is_SGAM_Page'
            WHEN owt.pageid IS NULL
                THEN NULL
            ELSE 'Is_not_PFS_GAM_SGAM_page'
            END AS blocked_spid_res_type
        ,(
            SELECT qt.TEXT AS [text()]
            FROM sys.dm_exec_sql_text(er.sql_handle) AS qt
            FOR XML PATH('')
                ,TYPE
            ) AS [blocked_batch]
        ,es.last_request_start_time AS blocked_last_start
        ,LEFT(CASE COALESCE(er.transaction_isolation_level, es.transaction_isolation_level)
                WHEN 0
                    THEN '0-Unspecified'
                WHEN 1
                    THEN '1-ReadUncommitted(NOLOCK)'
                WHEN 2
                    THEN '2-ReadCommitted'
                WHEN 3
                    THEN '3-RepeatableRead'
                WHEN 4
                    THEN '4-Serializable'
                WHEN 5
                    THEN '5-Snapshot'
                ELSE CONVERT(VARCHAR(30), er.transaction_isolation_level) + '-UNKNOWN'
                END, 30) AS blocked_tran_isolation_level
        ,er.total_elapsed_time / 1000 AS total_elapsed_time_sec
        ,
        -- blocker
        er2.session_id AS blocker_spid
        ,CASE 
            -- blocking session is either not blocked or has open trans
            WHEN owt.waiting_task_address IN (
                    SELECT owt2.blocking_task_address
                    FROM sys.dm_os_waiting_tasks owt2
                    )
                AND (
                    er2.session_id IS NULL
                    OR owt.blocking_session_id IS NULL
                    OR owt.[blocking_task_address] IS NULL
                    )
                THEN 1
            ELSE 0
            END AS is_head_blocker
        ,(
            SELECT qt2.TEXT AS [text()]
            FROM sys.dm_exec_sql_text(er2.sql_handle) AS qt2
            FOR XML PATH('')
                ,TYPE
            ) AS [blocker_batch]
        ,es2.last_request_start_time AS blocker_last_start
        ,LEFT(CASE COALESCE(er2.transaction_isolation_level, es2.transaction_isolation_level)
                WHEN 0
                    THEN '0-Unspecified'
                WHEN 1
                    THEN '1-ReadUncommitted(NOLOCK)'
                WHEN 2
                    THEN '2-ReadCommitted'
                WHEN 3
                    THEN '3-RepeatableRead'
                WHEN 4
                    THEN '4-Serializable'
                WHEN 5
                    THEN '5-Snapshot'
                ELSE CONVERT(VARCHAR(30), er2.transaction_isolation_level) + '-UNKNOWN'
                END, 30) AS blocker_tran_isolation_level
        ,
        -- other data
        DB_NAME(er.database_id) AS DBName
        ,es.host_name AS blocked_host
        ,es.program_name AS blocked_program
        ,es.login_name AS blocked_login
        ,CASE 
            WHEN es.session_id = - 2
                THEN 'Orphaned_distributed_tran'
            WHEN es.session_id = - 3
                THEN 'Deffered_recovery_tran'
            WHEN es.session_id = - 4
                THEN 'Unknown_tran'
            ELSE NULL
            END AS blocked_session_comment
        ,es.is_user_process AS [blocked_is_user_process]
        ,es2.host_name AS blocker_host
        ,es2.program_name AS blocker_program
        ,es2.login_name AS blocker_login
        ,CASE 
            WHEN es2.session_id = - 2
                THEN 'Orphaned_distributed_tran'
            WHEN es2.session_id = - 3
                THEN 'Deffered_recovery_tran'
            WHEN es2.session_id = - 4
                THEN 'Unknown_tran'
            ELSE NULL
            END AS blocker_session_comment
        ,es2.is_user_process AS [blocker_is_user_process]
    FROM (
        --In some cases (e.g. parallel queries, also waiting for a worker), one thread can be flagged as
        --waiting for several different threads.  This will cause that thread to show up in multiple rows
        --which is irrelevant.  Use ROW_NUMBER to select the longest wait for each thread
        SELECT [waiting_task_address]
            ,[session_id]
            ,[wait_duration_ms]
            ,[wait_type]
            ,[blocking_task_address]
            ,[blocking_session_id]
            ,[resource_description]
            ,CASE 
                WHEN [wait_type] LIKE 'PAGE%'
                    AND [resource_description] LIKE '%:%'
                    THEN CAST(RIGHT([resource_description], LEN([resource_description]) - CHARINDEX(':', [resource_description], LEN([resource_description]) - CHARINDEX(':', REVERSE([resource_description])))) AS INT)
                ELSE NULL
                END AS pageid
            ,ROW_NUMBER() OVER (
                PARTITION BY waiting_task_address ORDER BY wait_duration_ms DESC
                ) AS row_num
        FROM sys.dm_os_waiting_tasks --ORDER BY session_id
        ) owt
    INNER JOIN sys.dm_os_tasks ot ON ot.task_address = owt.waiting_task_address
    LEFT OUTER JOIN sys.dm_exec_requests er ON er.session_id = ot.session_id
        AND er.request_id = ot.request_id
    LEFT OUTER JOIN sys.dm_exec_sessions es ON es.session_id = er.session_id
    LEFT OUTER JOIN sys.dm_exec_sessions es2 ON es2.session_id = owt.blocking_session_id
    LEFT OUTER JOIN sys.dm_exec_requests er2 ON er2.session_id = owt.blocking_session_id
    OUTER APPLY sys.dm_exec_sql_text(er.sql_handle) est
    OUTER APPLY sys.dm_exec_query_plan(er.plan_handle) eqp
    WHERE owt.row_num = 1
        AND es.session_id <> @@SPID
        AND es.is_user_process = 1
    ORDER BY blocked_spid
        ,is_head_blocker DESC
        ,blocked_spid_wait_time_ms DESC
        ,blocker_spid
    GO
    

    使用扩展事件或BLOCKED_PROCESS_REPORT,您可以在发生阻塞时发现并收到警报。

    • 14

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve