當SQL Server 引擎接收到用戶發出的查詢請求時,SQL Server執行優化器將查詢請求(Request)和Task綁定,併爲Task分配一個Workder,SQL Server申請操做系統的進程(Thread)來執行Worker。若是以並行的方式執行Request,SQL Server根據Max DOP(Maximum Degree Of Parallelism) 配置選項建立新的Child Tasks,SQL Server將Request和多個Task綁定;例如,若是Max DOP=8,那麼將會存在 1個Master Task和 8 個Child Tasks。每一個Task綁定到一個Worker中,SQL Server引擎將分配相應數量的Worker來執行Tasks。sql
一,查看正在執行的請求(Request)session
使用 sys.dm_exec_requests 返回正在執行的查詢請求(Request)關聯的查詢腳本,阻塞和資源消耗。併發
1,查看SQL Server正在執行的查詢語句app
2,查看阻塞(Block)的語句cors
3,內存,IO,CPU消耗統計分佈式
二,查看SQL Server 當前正在執行的SQL查詢語句ide
在進行故障排除時,使用DMV:sys.dm_exec_requests 查看SQL Server當前正在執行的查詢語句:函數
select db_name(r.database_id) as db_name ,s.group_id ,r.session_id ,r.blocking_session_id as blocking ,s.login_name ,r.wait_type as current_wait_type ,r.wait_resource ,r.last_wait_type ,r.wait_time/1000 as wait_s ,r.status as request_status ,r.command ,r.cpu_time ,r.reads ,r.writes ,r.logical_reads ,r.total_elapsed_time ,r.start_time ,s.status as session_status ,substring( st.text, r.statement_start_offset/2+1, ( case when r.statement_end_offset = -1 then len(convert(nvarchar(max), st.text)) else (r.statement_end_offset - r.statement_start_offset)/2 end ) ) as individual_query from sys.dm_exec_requests r inner join sys.dm_exec_sessions s on r.session_id=s.session_id outer APPLY sys.dm_exec_sql_text(r.sql_handle) as st where ((r.wait_type<>'MISCELLANEOUS' and r.wait_type <> 'DISPATCHER_QUEUE_SEMAPHORE' ) or r.wait_type is null) and r.session_id>50 and r.session_id<>@@spid order by r.session_id asc
1,在故障排除時,能夠過濾掉一些無用的wait type 和當前Session:sqlserver
2,查看request執行的SQL查詢語句優化
sql_handle 字段表示當前查詢語句的句柄(handle),將該字段傳遞給sys.dm_exec_sql_text函數,將獲取Request執行的SQL語句,SQL Server對某些包含常量的查詢語句自動參數化(「Auto-parameterized」),獲取的SQL 查詢語句格式以下,SQL Server在查詢語句的開頭增長參數聲明:
(@P1 int,@P2 int,@P3 datetime2(7),@P4 datetime2(7)) WITH CategoryIDs AS (SELECT B.CategoryID, .....
兩個字段:stmt_start和stmt_end,用於標識參數聲明的開始和結尾的位置,使用這兩個字段,將參數聲明剝離,返回SQL Server執行的查詢語句。
3,阻塞
字段 blocking_session_id :阻塞當前Request的Session,但排除0,-2,-3,-4 這四種ID值:
三,查看SQL Server實例中活動的Task
使用DMV:sys.dm_os_tasks 查看當前實例中活動的Task
1,字段 task_state,標識Task的狀態
2,掛起的IO(Pending)
3,關聯的Request和Worker(associated)
4, Task Hierarchy
5,監控併發Request(Monitoring parallel requests)
For requests that are executed in parallel, you will see multiple rows for the same combination of (<session_id>, <request_id>).
SELECT session_id, request_id, task_state, pending_io_count, pending_io_byte_count, pending_io_byte_average, scheduler_id, context_switches_count, task_address, worker_address, parent_task_address FROM sys.dm_os_tasks ORDER BY session_id, request_id;
或利用 Task Hierarchy來查詢
select tp.session_id, tp.task_state as ParentTaskState, tc.task_state as ChildTaskState from sys.dm_os_tasks tp inner join sys.dm_os_tasks tc on tp.task_address=tc.parent_task_address
四,等待資源的Task(waiting)
使用DMV:sys.dm_os_waiting_tasks 查看系統中正在等待資源的Task
在對阻塞進行故障排除時,查看Block 和 爭用的資源:
select wt.waiting_task_address, wt.session_id, --Wait and Resource wt.wait_duration_ms, wt.wait_type, wt.resource_address, wt.resource_description, wt.blocking_task_address, wt.blocking_session_id from sys.dm_os_waiting_tasks wt
五,使用dbcc inputbuffer(spid)獲取spid最後一次執行的SQL語句
dbcc inputbuffer(spid)
六,休眠會話(Sleeping Session)
休眠的會話(Sleeping Session)表示當前的會話處於休眠狀態,該會話沒有運行任何Request。若是一個Session沒有運行任何Request,那麼該Session爲何不結束,而要保持休眠狀態?
休眠會話雖然沒有運行任何Request,可是,它和SQL Server的鏈接並無斷開,出現這種狀況的可能緣由主要有兩個:
1,查看休眠會話開啓的事務
SELECT db_name(dt.database_id) as database_name, dt.transaction_id, st.session_id, dt.database_transaction_begin_time, CASE dt.database_transaction_type WHEN 1 THEN 'Read/write transaction' WHEN 2 THEN 'Read-only transaction' WHEN 3 THEN 'System transaction' END database_transaction_type, CASE dt.database_transaction_state WHEN 1 THEN 'The transaction has not been initialized.' WHEN 3 THEN 'The transaction has been initialized but has not generated any log recorst.' WHEN 4 THEN 'The transaction has generated log recorst.' WHEN 5 THEN 'The transaction has been prepared.' WHEN 10 THEN 'The transaction has been committed.' WHEN 11 THEN 'The transaction has been rolled back.' WHEN 12 THEN 'The transaction is being committed. In this state the log record is being generated, but it has not been materialized or persisted' END database_transaction_state, dt.database_transaction_log_record_count, dt.database_transaction_log_bytes_used, dt.database_transaction_log_bytes_reserved FROM sys.dm_tran_database_transactions dt INNER JOIN sys.dm_tran_session_transactions st ON st.transaction_id = dt.transaction_id inner join sys.dm_exec_sessions s on st.session_id=s.session_id where s.status='sleeping'
2,查看休眠會話最後執行的TSQL語句
使用DBCC InputBuffer查看休眠會話最後執行的TSQL語句
dbcc inputbuffer(sleeping_session_id)
3,休眠會話可能產生阻塞
雖然休眠會話佔用的資源特別少,可是,若是休眠會話開啓的事務不能及時關閉,在某些特定狀況下,不只會阻止事務日誌的截斷(backup log 可以截斷Transaction log,減小日誌文件的增加,避免硬盤空間耗盡),甚至會阻塞其餘查詢。所以,在產品環境中,應當避免出現休眠會話。在開發程序時保證:打開一個鏈接,執行完相應的查詢語句以後,及時提交事務,關閉鏈接。
附件:引用《How to isolate the current running commands in SQL Server》,該文章描述瞭如何分離Request執行的查詢語句:
SELECT r.[statement_start_offset], r.[statement_end_offset], CASE WHEN r.[statement_start_offset] > 0 THEN --The start of the active command is not at the beginning of the full command text CASE r.[statement_end_offset] WHEN -1 THEN --The end of the full command is also the end of the active statement SUBSTRING(st.TEXT, (r.[statement_start_offset]/2) + 1, 2147483647) ELSE --The end of the active statement is not at the end of the full command SUBSTRING(st.TEXT, (r.[statement_start_offset]/2) + 1, (r.[statement_end_offset] - r.[statement_start_offset])/2) END ELSE --1st part of full command is running CASE r.[statement_end_offset] WHEN -1 THEN --The end of the full command is also the end of the active statement RTRIM(LTRIM(st.[text])) ELSE --The end of the active statement is not at the end of the full command LEFT(st.TEXT, (r.[statement_end_offset]/2) +1) END END AS [executing statement], st.[text] AS [full statement code] FROM sys.[dm_exec_requests] r CROSS APPLY sys.[dm_exec_sql_text](r.[sql_handle]) st WHERE r.session_id > 50 ORDER BY r.[session_id]
參考文檔:
Active Request, Sleeping Session
sys.dm_exec_requests (Transact-SQL)
sys.dm_os_tasks (Transact-SQL)