2

I have a transaction in a KILLED/ROLLBACK state and I want to make sure that sql is not dealing with it, meaning, there is no point in waiting for it to sort itself out.

the way I currently find out if the query is stuck is by using a query from our dear Pinal Dave, not sure of the exact link, but I got this query from him.

                        print @@servername
                        SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
                        SET NOCOUNT OFF

SELECT spid ,kpid ,login_time ,last_batch ,status ,hostname ,nt_username ,loginame ,hostprocess ,cpu ,memusage ,physical_io FROM sys.sysprocesses WHERE cmd = 'KILLED/ROLLBACK'

this works and through it I could conclude my session id is stuck.

nothing moves:

enter image description here

Also when I run this query here, I get a better picture:

enter image description here

It is clear to me that I will have to restart the service.

I also checked tempdb

        SELECT 
            g.database_id, 
            COUNT(vlf_sequence_number) AS VLF_Count
        FROM sys.dm_db_log_info(NULL) g 
        WHERE g.database_id = DB_ID()
        GROUP BY g.database_id

tempdb transaction log is growing (basically need to deal with it - restart the service)

enter image description here

Now it turns out that I would like to stop using sys.processes.

dbcc opentran

kill 61 with statusonly

enter image description here

question (finally)

How can I find if a spid is active without using sys.processes?

I did not include here on this question my main cause of concern. that would be how long it would take for the sql server service come back online, in this case I am nearly convinced that it would be a quick one, as it was not a long transaction, however, there is an availability group (manual failover, asynchronous commit) in the mix. none of these are part of this question. just mentioning for context.

Marcello Miorelli
  • 17,274
  • 53
  • 180
  • 320

2 Answers2

3

You can get all this info from dm_exec_requests and dm_exec_sessions. Just look for dm_exec_requests.status = 'rollback'.

You might find last_request_start_time and percent_complete useful as well.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT r.session_id ,s.login_time ,st.text as last_batch ,r.status ,s.host_name ,s.nt_user_name ,s.login_name ,s.cpu_time ,s.memory_usage ,s.reads ,s.writes ,s.last_request_start_time ,r.percent_complete ,r.command FROM sys.dm_exec_requests r LEFT JOIN sys.dm_exec_sessions s ON s.session_id = r.session_id OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) st WHERE r.command = 'KILLED/ROLLBACK'

Marcello Miorelli
  • 17,274
  • 53
  • 180
  • 320
Charlieface
  • 17,078
  • 22
  • 44
0

I have added a few things to this great script here and it is working for me:

/*
    This query shows sessions that are blocking other sessions, including sessions that are 
    not currently processing requests (for instance, they have an open, uncommitted transaction).
By:  Hannah Vernon, 2017-03-20

*/ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; --reduce possible blocking by this query.

USE tempdb;

IF OBJECT_ID('tempdb..#dm_tran_session_transactions') IS NOT NULL DROP TABLE #dm_tran_session_transactions; SELECT * INTO #dm_tran_session_transactions FROM sys.dm_tran_session_transactions;

IF OBJECT_ID('tempdb..#dm_exec_connections') IS NOT NULL DROP TABLE #dm_exec_connections; SELECT * INTO #dm_exec_connections FROM sys.dm_exec_connections;

IF OBJECT_ID('tempdb..#dm_os_waiting_tasks') IS NOT NULL DROP TABLE #dm_os_waiting_tasks; SELECT * INTO #dm_os_waiting_tasks FROM sys.dm_os_waiting_tasks;

IF OBJECT_ID('tempdb..#dm_exec_sessions') IS NOT NULL DROP TABLE #dm_exec_sessions; SELECT * INTO #dm_exec_sessions FROM sys.dm_exec_sessions;

IF OBJECT_ID('tempdb..#dm_exec_requests') IS NOT NULL DROP TABLE #dm_exec_requests; SELECT * INTO #dm_exec_requests FROM sys.dm_exec_requests;

;WITH IsolationLevels AS ( SELECT v.* FROM (VALUES (0, 'Unspecified') , (1, 'Read Uncomitted') , (2, 'Read Committed') , (3, 'Repeatable') , (4, 'Serializable') , (5, 'Snapshot') ) v(Level, Description) ) , trans AS ( SELECT dtst.session_id , blocking_sesion_id = 0 , Type = 'Transaction' , QueryText = dest.text FROM #dm_tran_session_transactions dtst LEFT JOIN #dm_exec_connections dec ON dtst.session_id = dec.session_id OUTER APPLY sys.dm_exec_sql_text(dec.most_recent_sql_handle) dest ) , tasks AS ( SELECT dowt.session_id , dowt.blocking_session_id , Type = 'Waiting Task' , QueryText = dest.text FROM #dm_os_waiting_tasks dowt LEFT JOIN #dm_exec_connections dec ON dowt.session_id = dec.session_id OUTER APPLY sys.dm_exec_sql_text(dec.most_recent_sql_handle) dest WHERE dowt.blocking_session_id IS NOT NULL ) , requests AS ( SELECT des.session_id , der.blocking_session_id , Type = 'Session Request' , QueryText = dest.text FROM #dm_exec_sessions des INNER JOIN #dm_exec_requests der ON des.session_id = der.session_id OUTER APPLY sys.dm_exec_sql_text(der.sql_handle) dest WHERE der.blocking_session_id IS NOT NULL AND der.blocking_session_id > 0 ) , Agg AS ( SELECT SessionID = tr.session_id , ItemType = tr.Type , CountOfBlockedSessions = (SELECT COUNT() FROM requests r WHERE r.blocking_session_id = tr.session_id) , BlockedBySessionID = tr.blocking_sesion_id , QueryText = tr.QueryText FROM trans tr WHERE EXISTS ( SELECT 1 FROM requests r WHERE r.blocking_session_id = tr.session_id ) UNION ALL SELECT ta.session_id , ta.Type , CountOfBlockedSessions = (SELECT COUNT() FROM requests r WHERE r.blocking_session_id = ta.session_id) , BlockedBySessionID = ta.blocking_session_id , ta.QueryText FROM tasks ta UNION ALL SELECT rq.session_id , rq.Type , CountOfBlockedSessions = (SELECT COUNT(*) FROM requests r WHERE r.blocking_session_id = rq.session_id) , BlockedBySessionID = rq.blocking_session_id , rq.QueryText FROM requests rq ) SELECT agg.SessionID , ItemType = STUFF((SELECT ', ' + COALESCE(a.ItemType, '') FROM agg a WHERE a.SessionID = agg.SessionID ORDER BY a.ItemType FOR XML PATH ('')), 1, 2, '') , agg.BlockedBySessionID , agg.CountOfBlockedSessions , agg.QueryText , des.host_name , des.login_name , des.is_user_process , des.program_name , des.status , TransactionIsolationLevel = il.Description ,des.cpu_time ,des.total_scheduled_time ,des.last_request_start_time ,des.reads ,des.writes ,des.logical_reads FROM agg LEFT JOIN #dm_exec_sessions des ON agg.SessionID = des.session_id LEFT JOIN IsolationLevels il ON des.transaction_isolation_level = il.Level GROUP BY agg.SessionID , agg.BlockedBySessionID , agg.CountOfBlockedSessions , agg.QueryText , des.host_name , des.login_name , des.is_user_process , des.program_name , des.status , il.Description ,des.cpu_time ,des.total_scheduled_time ,des.last_request_start_time ,des.reads ,des.writes ,des.logical_reads ORDER BY agg.BlockedBySessionID , agg.CountOfBlockedSessions , agg.SessionID;

enter image description here

Marcello Miorelli
  • 17,274
  • 53
  • 180
  • 320