サーバーに配置したsp_radheと呼ばれるストアドプロシージャがあり、内部で何が起こっているかを「確認」するのに役立ちました。
このストアドプロシージャのコードは次のとおりです。
USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--DROP PROCEDURE dbo.sp_radhe
GO
CREATE PROCEDURE dbo.sp_radhe
AS
/*
=======================================================================
Script : SP_RADHE
Author : Marcelo Miorelli
Date : 04 MAR 2013 Wednesday
Desc : shows the current processes
Usage : sp_radhe
-- same as sp_who2
=======================================================================
History
Date Action User Desc
-----------------------------------------------------------------------
27-oct-2014 changed Marcelo Miorelli commented out the line --and es.status = 'running'
so the procedure returns any es.status
=======================================================================
*/
--======================================
-- describe primary blocks of processing
--======================================
------------------------------------------------
-- describe action of logical groups of commands
------------------------------------------------
-- describe individual actions within a command set
BEGIN
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
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
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
--and es.status = 'running'
GO
exec sys.sp_MS_marksystemobject 'sp_radhe'
GO
ただし、アクティブではない他のプロセスによってプロセスがブロックされている場合、ブロックコードのT-SQLを理解するのに苦労しています。
例えば:
上の画像で確認できるセッション92は選択であり、セッション75はトランザクションを開いたままにした更新です。
セッション92
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SELECT TOP 1000 [accountID]
,[accountCreateKeyID]
,[totalAccountCreditValueLocal]
,[accountCreateDate]
,[createdDate]
,[createdBy]
,[modifiedDate]
,[modifiedBy]
FROM [TableBackups].[dbo].[_AO20150806_crm_build_account_DoNotDelete]
WITH (HOLDLOCK)
セッション75
BEGIN TRANSACTION T1
SELECT @@TRANCOUNT
update
[TableBackups].[dbo].[_AO20150806_crm_build_account_DoNotDelete]
set [totalAccountCreditValueLocal] = 1000
where accountID = 1
ブロッキングセッションのコード(この場合は、セッションのステータスが「スリープ中」の場合のセッション75)を見つけるにはどうすればよいですか?
新しいバージョンこの新しいバージョンはブロッキングセッションも表示しますが、スリープ状態のセッションからデータベース名やその他のデータを取得する方法を見つけることができませんでした。
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
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
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
UNION
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
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(ec.most_recent_sql_handle) AS st
where es.is_user_process = 1
and es.session_id <> @@spid
ブロッキングセッションのコード(この場合は、セッションのステータスが「スリープ中」の場合のセッション75)を見つけるにはどうすればよいですか?
新しいバージョンこの新しいバージョンはブロッキングセッションも示していますが、スリープ状態のセッションからデータベース名やその他のデータを取得する方法を見つけることができませんでした。
使用できます
SELECT db_name(S.database_id) AS DatabaseName,
ST.text
FROM sys.dm_exec_connections AS C
JOIN sys.dm_exec_sessions AS S ON S.session_id = C.session_id
OUTER APPLY sys.dm_exec_sql_text(most_recent_sql_handle) AS ST
WHERE C.session_id = 75;
詳細を追跡するには、Adam Machanicの SP_WHOISACTIVE を使用できます。
Sp_whoisactiveの優れた点の1つは、必要なデータを収集するためのテーブルを非常に迅速に生成してから、待機ステートメントを使用してループ内でプロシージャを実行し、一定の間隔で必要なデータを定期的に収集することです。この使用法は文書化されています。
ここで同じようにデータを収集する方法を参照してください: テーブルのsp_WhoIsActiveからのデータの収集