Sp_WhoIsActiveを使用すると、多くのプロセスが "スリープ"状態になり、数時間かかる場合があります。原因はわかりませんが、トラブルシューティングを続けています(タイムアウト?コミットされていないトランザクションの不良コード?)。
以下のクエリを使用すると、これらの開いているトランザクションはすべて、「スリープ」状態のSELECTクエリであることがわかりました。 SELECTがトランザクションを開くのはなぜですか?これらがストアドプロシージャのどこかにあり、[TEXT]フィールドに、実行されたプロシージャの最後のステートメントしか表示されていませんか?開いているトランザクションにはwait_infoがありません。
SELECT [TEXT] as SQLcode
FROM SYS.SYSPROCESSES SP
CROSS APPLY SYS.DM_EXEC_SQL_TEXT(SP.[SQL_HANDLE])AS DEST WHERE OPEN_TRAN=1
睡眠は必ずしも問題ではありません。アプリによっては、何も実行されていなくても、スレッドプーリングによって接続が開いたままになる場合があります。
開いているトランザクションがない場合、それは本当に問題ですか?
ケンドラ・リトルがこれについて最近書いた 彼女のブログ :
枕木は通常大丈夫です
開いているトランザクションのないスリープセッション…
テーブルにロックをかけていません
リソースをほとんど使用しません
アプリケーションで再利用できます(接続プーリングなど)
ケンダの提案に従って、sp_who2を使用する代わりに sp_whoisactive を確認してください。
以下のクエリを使い始めて、目的に合わせて調整してください。
select *
from sys.dm_tran_database_transactions t
join sys.dm_tran_session_transactions st on t.transaction_id = st.transaction_id
join sys.dm_exec_sessions s on s.session_id = st.session_id
join sys.dm_exec_connections c on c.session_id = s.session_id
cross apply sys.dm_exec_sql_text(most_recent_sql_handle)
where 1=1
and text <> 'begin tran'
and text not like '%sp_MS%'
and datediff(minute, last_request_end_time, getdate()) > 60
and database_transaction_begin_time is not null
私はこれを以下で使用します、それはほとんどの場合に役立ちます:
SELECT
es.session_id AS session_id
,CASE WHEN eS.LOGIN_NAME = eS.ORIGINAL_LOGIN_NAME
THEN eS.LOGIN_NAME
ELSE eS.LOGIN_NAME + ' (' + eS.ORIGINAL_LOGIN_NAME + ')'
END AS LOGIN_NAME
,es.Host_name AS hostname
,es.status
,es.last_request_start_time
,es.last_request_end_time
,es.CPU_TIME AS CPU_TIME_MS
,es.MEMORY_USAGE AS MEMORY_USAGE_PAGES
,es.ROW_COUNT
,NULL AS blocked_by
,NULL AS waittype
,NULL AS waittime
,NULL AS lastwaittype
,NULL AS waitresource
,dbid=trans.database_name
,NULL as cmd
,t.text AS [QUERY]
,NULL AS PARENT_QUERY
,TRANSACTION_ISOLATION_LEVEL = NULL
,NULL as cpu
,NULL AS physical_io
--,es.open_transaction_count as [open_tran]
,es.program_name
--,es.login_time
--,ota.task_state
--,ota.pending_io_count
--,ota.pending_io_byte_count
FROM sys.dm_exec_sessions AS es
INNER JOIN sys.dm_exec_connections AS c
ON es.session_id = c.session_id
--LEFT OUTER JOIN sys.dm_os_tasks ota ON es.session_id = ota.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 es.session_id = st.session_id
) AS trans
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) AS t
WHERE es.session_id NOT IN (
SELECT session_id
FROM sys.dm_exec_requests
)
AND es.session_id IN (
SELECT request_session_id
FROM sys.dm_tran_locks
WHERE request_status = 'GRANT'
)
AND STATUS = 'sleeping'
AND is_user_process = 1
AND es.session_id <> @@spid
SYS.SYSPROCESSESの使用は避けてください