13:05 2015/9/11 午睡醒来收到几封CPU使用率预警邮件。登录对应服务器,打开资源监视器,看到sqlservr.exe进程的CPU达到40%(平常服务器CPU消耗在10%以内)。查看CPU信息跟踪表,近一小时的CPU都维持在40%左右。

图1 CPU使用率预警邮件

图2 资源监视器和CPU信息跟踪表
开启profiler跟踪,筛选CPU>60毫秒的事件。发现有一个存储过程调用非常频繁,而且cpu>90 read>2800。查看此过程,语句很简单,返回记录数很少,表上有对应索引。但从profiler所得开销看,语句肯定没有使用索引。之前遇到类似的问题,只需删除存储过程的计划缓存,cpu、read就降下去了。

--返回做IO数目最多的存储过程以及它们的执行计划(微秒)
SELECT TOP 20 DB_NAME(a.database_id) DBname
,OBJECT_NAME(OBJECT_ID ,database_id) 'proc name'
,a.cached_time
,a.last_execution_time
,a.execution_count
,a.last_logical_reads
,a.total_logical_reads / a.execution_count avg_logical_reads
,a.total_logical_writes / a.execution_count avg_logical_writes
,a.total_physical_reads / a.execution_count avg_physical_reads
--,a.total_worker_time / a.execution_count AS avg_worker_time
,a.total_elapsed_time / a.execution_count avg_elapsed_time
--,b.text
,c.query_plan
,a.plan_handle
FROM sys.dm_exec_procedure_stats AS a
CROSS APPLY sys.dm_exec_sql_text(a.sql_handle) b
CROSS APPLY sys.dm_exec_query_plan(a.plan_handle) c
where OBJECT_NAME(OBJECT_ID ,database_id) ='ProcName'
ORDER BY
a.total_logical_reads/a.execution_count desc --DBCC FREEPROCCACHE(0x0500080094EA1B2F40A1B3DE000000000000000000000000)


图3 处理前消耗情况

图4 处理后消耗情况

图5 半分钟内过程调用情况
问题现象很明显(不定期会重现),就是一个很简单的过程,频繁调用,突然在某个时间点,过程消耗变得很大;只要把对应缓存计划删除,消耗立马降下去。问题的本质是执行计划的变更。过程最开始执行(或者手动执行时)走的是索引查找+键查找;出问题的时候变成了聚集索引扫描!

图6 手动执行时的执行计划
查看CPU信息跟踪表,找出此次CPU上涨的起始时间(2015-09-11 11:15:51.447)。查询过程涉及表所依赖的存储过程,查询是否有作业对表(直接或者通过存储过程)进行数据变更,分析表中数据变更与CPU上涨的时间是否吻合。

--表依赖的过程
select name,object_id,text from sys.procedures a,syscomments b
where a.object_id=b.id and text like '%Table%'
--作业调用的表/过程
select top 3 sj.name,sjs.command
from msdb.dbo.sysjobs sj
inner join msdb.dbo.sysjobsteps sjs
on sj.job_id=sjs.job_id
where sjs.command like '%TableOrProc%'

发现有两个过程,被两个作业调用,有对表中数据清空然后再写入。其中一个作业是每天凌晨03:03(排除),另一个作业是每小时执行一次。查看每小时执行一次的作业历史记录,发现在11:15的时候作业耗时46秒,其他时候基本为0。也就是那个时间点对表中数据进行了清空再写入的操作。

--查看作业执行情况
select top 20 sj.name,sjh.step_id,sjh.message,sjh.run_status
,msdb.dbo.agent_datetime(run_date,run_time) run_time,sjh.run_duration
from msdb.dbo.sysjobhistory sjh
inner join msdb.dbo.sysjobs sj
on sjh.job_id=sj.job_id
where sj.name='jobname'
order by msdb.dbo.agent_datetime(run_date,run_time) desc


图7 作业历史执行时间
查询统计信息更新时间

SELECT STATS_DATE(object_id,stats_id) statsdate,* FROM sys.stats


图8 统计信息更新时间
数据清空再写入,导致统计信息更新,进而影响执行计划?现在查看统计信息是在11:15更新的,会不会是刚好清空表的时候,程序调用了过程,表中没数据,生成了一个表扫描的执行计划,之后就一直重用这个计划?总之就是表数据变更(清空)影响统计信息,进而影响执行计划的重新生成(表扫描),接着数据再次写入,统计信息会再次更新,但执行计划却还是旧的(表扫描),导致消耗变大。如果手动执行,它会依据新的统计信息,生成新的执行计划(索引查找+键查找)……找个时间测试下
12:05 2015/9/21 出现同样的现象,查看异常时高CPU过程缓存情况,显示的cached_time(2015-09-19 11:16:03.320)

图9 异常时的过程缓存
滚动条拉到后面,查看过程对应的执行计划(query_plan)

图10 异常时的执行计划
查看CPU信息跟踪表,找出此次CPU上涨的起始时间,意外地是这次并不像上次那样CPU一下就窜到40%,而是从早上(2015-09-21 07:16:07.153)涨到10%,然后一直维持在10%并逐渐上涨,7-11点偶尔会超过40%,但没有达到触发邮件提醒的条件。在(2015-09-21 12:05:00.437)服务器发出预警邮件。
分别在过程缓存的cached_time和CPU上涨的时间表点查看作业执行情况,单独从作业执行时间来看,每小时执行的作业根本就没有执行清空再写入的步骤

图11 cached_time前后作业执行时间

图12 CPU上涨前后作业执行时间
查看与清空表相关的过程对应的缓存情况

图13 作业1调用过程pro1

图14 作业2调用过程pro2
作业1计划是每天凌晨03:03执行一次,截图中cached_time(2015-09-20 03:03:00.497),last_execution_time(2015-09-21 12:06:01.050),但执行次数却高达32次。应该是其他地方有调用这个过程,查询没有依赖的过程,也没有其他作业调用此过程。
作业2是(03:15-22:59)每小时执行一次,从截图看恰好是42次。作业2调用的过程pro2,实际是先判断两张表的记录数是否一致,不一致就调用过程pro3(清空表再插入)。但是在缓存中却没有看到pro3的缓存情况。这就表明作业2是按计划执行,调用过程pro2,pro2检查表中记录数一直保持一致,所以就跳过没有执行过程pro3。
根据各过程缓存时间点,及CPU上涨时间,大致推测此次异常应该是由过程pro1引起(但不是作业1引起的),重点跟踪此过程的执行情况!
18:01 2015/9/24 收到CPU使用率预警邮件,查看异常时高CPU过程缓存情况,显示的cached_time(2015-09-24 07:24:06.050)


图15 异常时的过程缓存
查看与清空表相关的过程对应的缓存情况

图16 作业2调用过程pro2

图17 过程pro2调用pro3
作业2是(03:15-22:59)每小时执行一次,从截图看恰好是10次。作业2调用的过程pro2,实际是先判断两张表的记录数是否一致,不一致就调用过程pro3(清空表再插入)。pro3显示的cached_time(2015-09-24 14:15:00.717),execution_count(1),CPU信息跟踪表,此次CPU上涨的起始时间(2015-09-24 14:16:18.840)。基本可以确定作业2在14:15执行时调用了过程pro3,表中数据变更引起统计信息的变更,然后引起执行计划的重新生成,最终体现就是CPU上涨。只是当时的CPU消耗尚未达到触发邮件提醒的条件。

图18 CPU信息跟踪表

TRUNCATE引起CPU异常上涨的更多相关文章

  1. 软件调试——CPU异常列表

    CPU异常主要分为三类:错误类异常,陷阱类异常和终止类异常 1 错误类异常 Fault CPU遇到该类异常后,会先将CS和EIP(当前发生错误的指令,而不是下一条指令)压栈,然后跳到异常处理函数中,执 ...

  2. CPU异常分析(以trap00为例)

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html CPU异常的记录(trap00为例) 一.CPU检测到除零异常的执 ...

  3. 两种异常(CPU异常、用户模拟异常)的收集

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 两种异常(CPU异常.用户模拟异常)的收集  文章的核心:异常收集 ...

  4. 一次死锁导致CPU异常飘高的整个故障排查过程

    目录 一.问题详情 top 命令截图 联系腾讯云排查 检查系统日志发现异常 二. 问题解析 三.问题原因 最终结论 四.扩展 进程的几种状态 马后炮 如何快速清理僵尸进程(Z) 内核参数相关 如何查看 ...

  5. 副本集mongodb 无缘无故 cpu异常

    mondb 服务器故障 主从复制集 主:   192.168.1.106从:   192.168.1.100仲裁:192.168.1.102 os版本:CentOS Linux release 7.3 ...

  6. 由Java正则表达式的灾难性回溯引发的高CPU异常:java.util.regex.Pattern$Loop.match

    问题与分析 某天领导report了一个问题:线上的CPU自从上一个版本迭代后就一直处于居高不下的状况,领导看着这段时间的曲线图判断是有两条线程在不停的死循环. 接到任务后去查看了AWS的CloudWa ...

  7. 记录一次redis cpu异常升高的排插思路

    好久没有写博客  现在重新捡起来  记录工作中遇到的问题  方便以后在遇到类似的问题也有一个参考. 背景:有一天生产服务器redis  cpu 频繁报警    单核cpu 所以在想是不是业务量上来了. ...

  8. windbg 分析cpu异常

    1.   !threadpool  查看当前CPU状况 线程数等等 2.   !runaway 查看那几个线程使用的高 建议多抓几个dump 然后确定到底是哪个线程 3.   ~线程IDs 跳转到那个 ...

  9. 一条语句导致CPU持续100%

    一大早收到一堆CPU预警邮件,通常每天只在统计作业执行期间会收到2~3封CPU预警邮件.这次的预警来自另一台服务器,并且明细数据显示其CPU一直维持在49%.登录到服务器,查看任务管理器(查看资源监视 ...

随机推荐

  1. [APAC]导入图片至Word,然后按规则命名(2/2)

    #将所有docx文件改成可读 Set-ItemProperty -Path "e:\screenshot\*.docx" -Name IsReadOnly -Value $fals ...

  2. Maven 私有库 Nexus的安装

    1.下载 Nexus下载地址:http://www.sonatype.org/nexus/go/ # wget https://sonatype-download.global.ssl.fastly. ...

  3. HDU 1069 基础动态规划+排序

    题意 给出n种立方体石头 当且仅当一块石头的底部宽度长度都小于一块石头的时候才能放在上面 问最高能放多高?石头不限数目 然而同样一种石头采用同样的摆放方式 两快相同石头一定无法进行放置 所以 一块石头 ...

  4. HDR Defered Shading (using MRT)

    http://http.download.nvidia.com/developer/SDK/Individual_Samples/DEMOS/Direct3D9/DeferredShading.zip ...

  5. Gao Big 深圳行

    day 1 来到深圳的国际化大都市之后,首先要做的事情就是···坐地铁?? 到了旅店,已经比较晚了,又折腾了两三下.. day 2 第二天一早,一行人出发来到深圳大学(nv shen su she)参 ...

  6. PHP+jQuery 列表分页类 ( 支持 url 分页 / ajax 分页 )

    /* ******* 环境:Apache2.2.8 ( 2.2.17 ) + PHP5.2.6 ( 5.3.3 ) + MySQL5.0.51b ( 5.5.8 ) + jQuery-1.8.3.mi ...

  7. 一些Discuz!代码

    首行缩进2字符 [code][p=20, 2, left]首行缩进2字符[/p][/code]

  8. 第二章、 Linux 如何学习

    第二章. Linux 如何学习 最近更新日期:2009/08/06 1. Linux当前的应用角色 1.1 企业环境的利用 1.2 个人环境的使用 Linux当前的应用角色 在第一章Linux是什么当 ...

  9. Least_squares 最小二乘法

    https://en.wikipedia.org/wiki/Least_squares 動差估計法( MM, The Method of Moment ) 最小平方法( LSQ, The Method ...

  10. Mac 下 命令收藏

    1.查看文件的二进制 xxd -b test.wav 2.所有占用的端口 sudo lsof -i -P | grep -i "listen" 原文地址:Mac 下 命令收藏标签: ...