web-dev-qa-db-ja.com

ブロッキングを引き起こしているスリーププロセスに関する情報を取得する方法

SQLサーバーで現在何が実行されているか を確認できる手順があります

このプロシージャは廃止されたため、sys.sysprocessを 使用しません

ただし、ブロッキングを引き起こしているスリーププロセスに関する必要な情報を見つけるのに苦労しています。

これは、DMV sys.dm_exec_requests がスリーププロセスの要求を保持しないためです。

sp_whoisactive やその他の監視ツールを使用したくありません。 sp_whoisactiveはsys.sysprocessesを使用します。

セッション81があります:

  BEGIN TRANSACTION T1

  SELECT @@TRANCOUNT

  update 
  [TableBackups].[dbo].[spstats]
  set execution_count  = 1000
  where dbname = 'master'

  select @@spid

そして私は私のセッション51を持っています:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

SELECT TOP 1000 *
  FROM [TableBackups].[dbo].[spstats]
  WITH (HOLDLOCK)

上記の2つのセッションは同時に実行されているため、セッション81がセッション51をブロックしています。

セッション81に関する情報を取得する以下を選択しましたが、dbidを取得できませんでした。Open_transactionsと待機情報全体についてはわかりません。

SELECT es.session_id AS session_id
,COALESCE(es.original_login_name, 'No Info') AS login_name
,COALESCE(es.Host_name,'No Info') AS hostname
,COALESCE(es.last_request_end_time,es.last_request_start_time) AS last_batch
,es.status
,COALESCE(er.blocking_session_id,0) AS blocked_by
,COALESCE(er.wait_type,'MISCELLANEOUS') AS waittype
,COALESCE(er.wait_time,0) AS waittime
,COALESCE(er.last_wait_type,'MISCELLANEOUS') AS lastwaittype
,COALESCE(er.wait_resource,'') AS waitresource
,coalesce(db_name(er.database_id),'No Info') as dbid
,COALESCE(er.command,'AWAITING COMMAND') AS cmd
,sql_text=st.text
,transaction_isolation =
    CASE es.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
,COALESCE(es.cpu_time,0) 
    + COALESCE(er.cpu_time,0) AS cpu
,COALESCE(es.reads,0) 
    + COALESCE(es.writes,0) 
    + COALESCE(er.reads,0) 
    + COALESCE(er.writes,0) AS physical_io
,COALESCE(er.open_transaction_count,-1) AS open_tran
,COALESCE(es.program_name,'') AS program_name
,es.login_time
FROM sys.dm_exec_sessions es
    INNER JOIN sys.dm_exec_requests ec2 ON es.session_id = ec2.blocking_session_id
    LEFT OUTER JOIN sys.dm_exec_connections ec ON es.session_id = ec.session_id
    LEFT OUTER JOIN sys.dm_exec_requests er ON es.session_id = er.session_id
    LEFT OUTER JOIN sys.server_principals sp ON es.security_id = sp.sid
    CROSS APPLY sys.dm_exec_sql_text(ec.most_recent_sql_handle) AS st
where es.is_user_process = 1 
  and es.session_id <> @@spid

問題は、sys.sysprocesses以外に、この情報を取得するために使用できるDMVはありますか?

3

これは、ブロッキングの問題を引き起こしているスリープ状態のSPIDを監視するために使用するものです。

SELECT 
    ,s.session_id
    ,s.status
    ,s.login_time
    ,s.Host_name
    ,s.program_name
    ,s.Host_process_id
    ,s.original_login_name
    ,s.last_request_end_time
    ,CAST(t.text AS nvarchar(4000)) AS [text]
FROM sys.dm_exec_sessions AS s
INNER JOIN sys.dm_exec_connections AS c
    ON s.session_id = c.session_id
CROSS APPLY (
    SELECT MAX(DB_NAME(dt.database_id)) AS database_name
    FROM sys.dm_tran_session_transactions AS st
    INNER JOIN sys.dm_tran_database_transactions AS dt
        ON st.transaction_id = dt.transaction_id
    WHERE is_user_transaction = 1
    GROUP BY st.session_id
    HAVING s.session_id = st.session_id 
) AS trans
CROSS APPLY sys.dm_exec_sql_text(most_recent_sql_handle) AS t
WHERE s.session_id NOT IN (
        SELECT session_id
        FROM sys.dm_exec_requests
    )
    AND s.session_id IN (
        SELECT request_session_id
        FROM sys.dm_tran_locks
        WHERE request_status = 'GRANT'
    )
    AND STATUS = 'sleeping'
    AND is_user_process = 1;

お役に立てれば。

質問に具体的に答えるために、sys.dm_tran_database_transactionsは、探している情報を保持します。

4
spaghettidba