一个MySQL服务CPU100的优化案

这是学习笔记的第篇文章

昨天在快下班的时候和同事处理了一起性能故障导致的服务器CPU%的案例。虽然问题解决了,但是在事后我做了一些反思,总体来说不够乐观。

其实这几年救火处理性能故障的情况已经越来越少了,我不知道是不是一种错觉,所以会看到很多DBA在不断的思考人生,思考DBA存在的价值,这个过程可长可短,但是归根结底的问题其实还是一样的:处理问题的价值和个人的价值是否持久。

我们来看下这个案例,我会弱化一些问题的描述,而更多是在问题本身的思考上面。

快下班的时候,突然收到了一堆MySQL慢日志报警,同事反馈说晚上有一波活动,这个时候已经距离活动的开启时间很近了,然后就发现服务器的CPU瞬间到了%,确切的说系统的负载在70倍左右。

这是当时的一个系统负载情况:

top-19:11:13updays,2:19,3users,loadaverage:76.87,45.35,34.26

Tasks:total,2running,sleeping,0stopped,0zombie

Cpu(s):99.2%us,0.5%sy,0.0%ni,0.1%id,0.0%wa,0.0%hi,0.2%si,0.0%st

Mem:ktotal,kused,kfree,kbuffers

Swap:ktotal,0kused,kfree,kcached

这是一个很熟悉的场景,我们处理问题的思路也很自然,查看慢日志,查看瓶颈SQL,很可能找出一些全表扫描的表,然后添加索引,接着系统负载瞬间跌下来,然后业务活动继续,我们送了一口气。

实际上却不是这样的。

一方面产生的慢日志过多,没几分钟就产生了上G的慢日志,所以很快抓取慢日志的方法不大可行,而且从补救的角度,我们关闭了参数log_queries_not_using_indexes,防止产生过多的慢日志。

另外一方面,我们发现产生慢日志的表还挺多,不是添加一个两个索引就能够快速解决的。

事情到了这里似乎有一些失控的状态。

我们需要快速定位问题,然后根据SQL的执行情况添加合适的索引,尽可能给活动争取时间。如果是你该如何处理?当时背后已经站了好几个人,大家都希望奇迹出现的时刻。

当时我是临时开启了参数log_queries_not_using_indexes,得到了一些补充的慢日志信息,然后快速关闭,拿pt工具做了下分析,很快得到了一个简单的报告内容:

然后针对这几条语句开始优化,很快按照查询情况添加了索引,业务再次尝试,负载还是很高。

这个时候我们查看showprocesslist的结果,发现有大量的线程锁定在同一张表上,而且返回的事件是sendingdata,那么很显然和一个全表扫描相关了。

这个语句的逻辑是selectcount(1)fromxxxxwherexxxx;

再次添加了索引之后,问题得到了解决,后续做了些收尾,算是告一段落。

当然如果是在10年前,我觉得是一个很有意思的案例了。但是我的内心的成就感其实不是很高,一方面来说,添加索引这种优化方法简直就是DBA优化的送分题,而且这种优化是属于规范化流程之外的救火行为,有什么可以值得宽慰和满足的。

为什么会出现这个问题,除了业务方的准备不够充分外,我觉得还有很多补充的细节。

我们是否对慢日志给予了高度的


转载请注明:http://www.aierlanlan.com/rzdk/5270.html