当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)