web-dev-qa-db-ja.com

spidのステータスが一時停止されている理由を調べる方法は? spidが待機しているリソースは何ですか?

走る EXEC sp_who2 78と私は次を取得します 結果

results of sp_who2 for spid 78

ステータスが一時停止になっている理由を確認するにはどうすればよいですか?

このプロセスは、高価なクエリに基づく重いINSERTです。複数のテーブルからデータを取得し、約300〜400万行を別のテーブルに書き込む大きなSELECT

ロック/ブロックはありません。

リンク先のwaittypeCXPACKETです。下の写真でわかるように9個の78があるので、これは理解できます。

私に関係し、本当に知りたいのは、SPID 78の1番が中断されている理由です。

SPIDのステータスが一時停止されると、プロセスはリソースを待機しており、リソースを取得すると再開することを理解しています。

これに関する詳細をどのように見つけることができますか?どのリソースですか?なぜ利用できないのですか?

以下のコードとそのバリエーションを多く使用しますが、SPIDが停止している理由を見つけるために他にできることはありますか?

select * 
from sys.dm_exec_requests r
join sys.dm_os_tasks t on r.session_id = t.session_id
where r.session_id = 78

すでに sp_whoisactive を使用しました。この特定のspid78の結果は次のとおりです(画面に合わせて3枚に分割されます)。

enter image description here

32

SUSPENDED:リソースを待機しているため、リクエストは現在アクティブではないことを意味します。リソースはページを読み取るためのI/Oであるか、WAITitはネットワーク上の通信であるか、ロックまたはラッチを待機しています。待機しているタスクが完了するとアクティブになります。たとえば、クエリが完全なテーブルtblStudentsのデータを読み取るためのI/O要求を送信した場合、このタスクはI/Oが完了するまで中断されます。 I/Oが完了すると(テーブルtblStudentsのデータがメモリで利用可能になります)、クエリはRUNNABLEキューに移動します。

したがって、待機している場合は、wait_type列を確認して、待機しているものを理解し、wait_timeに基づいてトラブルシューティングを行います。

これに役立つ次の手順を開発しました。これにはWAIT_TYPEが含まれています。

use master
go

CREATE PROCEDURE [dbo].[sp_radhe] 

AS
BEGIN

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT es.session_id AS session_id
,COALESCE(es.original_login_name, '') AS login_name
,COALESCE(es.Host_name,'') 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
    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
    LEFT OUTER JOIN sys.dm_os_tasks ota ON es.session_id = ota.session_id
    LEFT OUTER JOIN sys.dm_os_threads oth ON ota.worker_address = oth.worker_address
    CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS st
where es.is_user_process = 1 
  and es.session_id <> @@spid
ORDER BY es.session_id

end 

以下のこのクエリは、spidが待機しているリソースを表示することにより、spidが中断されたときに役立つ基本情報も表示できます。

SELECT  wt.session_id, 
    ot.task_state, 
    wt.wait_type, 
    wt.wait_duration_ms, 
    wt.blocking_session_id, 
    wt.resource_description, 
    es.[Host_name], 
    es.[program_name] 
FROM  sys.dm_os_waiting_tasks  wt  
INNER  JOIN sys.dm_os_tasks ot ON ot.task_address = wt.waiting_task_address 
INNER JOIN sys.dm_exec_sessions es ON es.session_id = wt.session_id 
WHERE es.is_user_process =  1 

例として以下の図を参照してください。

enter image description here

31

Sp_whoIsActiveを使用してこの種の情報を確認します。これは、遅いクエリのトラブルシューティングに役立つ情報を提供する既製の無料ツールです。

sp_WhoIsActiveを使用して低速のSQL Serverクエリを検索する方法

これにより、クエリテキスト、使用しているプラ​​ン、クエリが待機しているリソース、ブロックしているもの、取り出しているロックなどを取得できます。

自分でロールバックするよりもはるかに簡単です。

12
steoleary