J'ai une procédure stockée appelée SP_RADHE que je mets sur mes serveurs et que cela m'aidait à "voir" Qu'est-ce qui se passe en interne.
voici le code de cette procédure stockée:
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
Cependant, lorsqu'un processus est bloqué par un autre processus qui n'est pas actif, je suis en difficulté de comprendre le T-SQL du code de blocage.
Par exemple:
la session 92 que vous pouvez voir sur la photo ci-dessus est une sélection et la session 75 est une mise à jour que j'ai laissée la transaction ouverte.
Session 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)
Session 75
BEGIN TRANSACTION T1
SELECT @@TRANCOUNT
update
[TableBackups].[dbo].[_AO20150806_crm_build_account_DoNotDelete]
set [totalAccountCreditValueLocal] = 1000
where accountID = 1
Comment puis-je trouver le code de la session de blocage, dans ce cas, la session 75 lorsque le statut de la session est "Dormir"?
Nouvelle version Cette nouvelle version affiche également la session de blocage, cependant, je n'ai pas pu savoir comment obtenir le nom de la base de données et d'autres données d'une session de sommeil.
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
Comment puis-je trouver le code de la session de blocage, dans ce cas, la session 75 lorsque le statut de la session est "Dormir"?
Nouvelle version Cette nouvelle version indique également la session de blocage, cependant, je n'ai pas pu savoir comment obtenir le nom de la base de données et d'autres données d'une session de sommeil.
Vous pouvez utiliser
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;
Vous pouvez utiliser Adam Machanic's sp_whoisactiveactive pour obtenir les détails suivis.
L'une des grandes choses sur SP_WhoisActive est qu'il est très rapide de générer une table pour collecter les données dont vous avez besoin, puis exécutez la procédure dans une boucle avec une déclaration d'attente pour collecter régulièrement les données que vous souhaitez sur un intervalle. Cette utilisation est documentée.
S'il vous plaît voir sur la façon de collecter les données pour les mêmes ici: collecte de données de sp_whoisactive dans une table