SQL Server 持续占用30%CPU,如何排查是挖矿还是正常运行?
查看SQL Server当前执行操作的替代方法
核心排查脚本(活动监视器失效时首选)
你可以直接执行以下DMV查询,获取当前所有正在运行的请求、关联SQL文本、CPU占用等核心信息:
SELECT r.session_id, r.status, r.cpu_time, r.total_elapsed_time, SUBSTRING(qt.text, (r.statement_start_offset/2)+1, ((CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(qt.text) ELSE r.statement_end_offset END - r.statement_start_offset)/2)+1) AS executing_sql, qt.text AS full_query_text, s.login_name, s.host_name FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) qt LEFT JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id WHERE r.session_id <> @@SPID -- 排除当前查询会话 ORDER BY r.cpu_time DESC
无可见作业/查询时高CPU问题排查
如果执行上述脚本也没有找到明显的用户查询,优先排查以下几类隐藏的消耗源:
- 系统后台任务:比如ghost清理、自动统计更新、checkpoint、异步索引维护等系统级任务,不会出现在普通用户作业列表中,可通过
SELECT * FROM sys.dm_os_background_tasks WHERE state = 'RUNNING'查询确认 - 高频轻量查询:单次执行CPU消耗很低但调用频次极高的查询,累计会导致CPU持续居高,可通过以下脚本查询计划缓存中累计CPU最高的查询:
SELECT TOP 20 SUBSTRING(qt.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(qt.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)+1) AS statement_text, qs.total_worker_time/1000 AS total_cpu_ms, qs.execution_count, qs.total_worker_time/qs.execution_count/1000 AS avg_cpu_per_execution_ms FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt ORDER BY qs.total_worker_time DESC
- 异常空闲连接:部分应用连接未正确释放,持有锁或事务导致后台资源持续消耗,可查询
sys.dm_exec_sessions筛选长时间处于活跃状态的非系统会话验证
内容的提问来源于stack exchange,提问作者skk
相关产品推荐
相关产品推荐

