MySQL 高 CPU 使用率

211

最近我的服务器CPU占用率很高。

CPU负载平均值为13.91(1分钟),11.72(5分钟),8.01(15分钟),而我的网站只有轻微的访问量增加。

运行top命令后,我发现MySQL正在使用160%的CPU!

最近我一直在优化表并切换到持久连接。这会导致MySQL使用大量CPU吗?


4
持久连接几乎总是不适合使用的。 - jason
我现在会把它们关掉,并观察是否有任何变化,因为我绝对不记得一个月前 CPU 使用率曾经超过 2。 - Juddling
2
服务器通常具有多个核心。百分比CPU使用率是相对于一个核心计算的,换句话说,完全使用两个核心的进程将具有200%的CPU使用率。在这里,MySQL正在使用一个核心的100%和另一个核心的60%。这并不意味着所有CPU都被使用了,很可能他仍然至少有两个空闲的CPU。 - xaav
高 CPU 使用率几乎总是意味着查询效率低下。这种情况通常可以通过更好的索引(特别是“复合”索引)和/或重新构造查询来解决。 - Rick James
3个回答

288

首先,我建议您关闭持久连接,因为它们几乎总是带来更多的伤害而不是好处。

其次,我建议您仔细检查MySQL用户,以确保没有人可以从远程服务器连接。这也是一个重要的安全问题需要检查。

第三,我建议您开启MySQL慢查询日志,以监视任何长时间运行的查询,并使用它来确保没有查询锁定关键表太长时间。

您还可以在CPU负载高时运行以下查询来检查其他内容:

SHOW PROCESSLIST;

这将显示当前正在运行或排队等待运行的任何查询,查询内容和查询执行情况(如果查询太长,此命令将截断查询,您可以使用SHOW FULL PROCESSLIST查看完整的查询文本)。
您还需要关注缓冲区大小、表缓存查询缓存innodb_buffer_pool_size(如果使用innodb表),因为所有这些内存分配都可能影响查询性能,从而导致MySQL占用CPU。
您还可能想阅读以下内容,因为它们包含了一些很好的信息。

使用分析器也是一个非常好的主意。可以在需要时打开,显示应用程序正在运行的查询、是否有重复查询以及它们花费的时间等等。这样的示例之一是我正在开发的PHP Profiler,但市面上有许多类似的工具。如果您正在使用Drupal、Joomla或WordPress等软件,您可能需要在社区中寻求帮助,因为它们可能已经为这些软件提供了模块,无需手动集成即可获取此信息。


13
非常感谢您。我移除了持久连接并设置了慢查询日志。我读取了日志,发现大多数查询来自于两个表,这些表没有被正确地索引!虽然只过去了10分钟,但是现在的结果是:CPU 负载平均值为 0.48 (1 分钟)、0.95 (5 分钟)、2.42 (15 分钟)非常感谢。 - Juddling
1
同样的问题,通过对减慢进程的表进行索引解决了,感谢Steven和Juddling。 - gabrielem
@Juddling,您能详细说明如何对表进行索引吗?或者提供一些链接?我知道这已经过去一段时间了,但我真的很新手。对于这个问题感到抱歉。 - JayVDiyk
记录慢查询帮助我找到了高CPU利用率的问题所在。在我的情况下,是一个WordPress插件(ultimate-tag-cloud-widget)每次访问都会执行一次巨大的查询来显示热门标签。这是一个很棒的插件,但需要增加某种缓存功能(最终我进行了自定义以解决我的问题)。 - jkincali
1
另一个有帮助的解决方案是修改上面提到的参数innodb_buffer_pool_size。在尝试找出高CPU利用率的原因时,我在某个地方读到,innodb_buffer_pool_size应该至少与位于/var/lib/mysql中的文件ibdata1的大小相同。当InnoDB能够驻留在内存中时,它似乎可以更有效地工作。在某些情况下,这可能很难做到,因为ibdata1可能非常大!还建议确保innodb_log_buffer_size是innodb_buffer_pool_size大小的25%。 - jkincali
还有一个SHOW FULL PROCESSLIST命令,它显示完整的查询语句,对我来说,它显示了ORM系统生成的大型连接。 - Aleksandar Pavić

173

作为谷歌MySQL高CPU使用率或负载的最热门帖子,我将添加另一个答案:

在2012年7月1日,由于潮汐引起地球自转减缓,一个闰秒被加到当前的UTC时间中。当运行ntp(或ntpd)时,这一秒被添加到您计算机/服务器的时钟中。MySQLd似乎不喜欢某些操作系统上的这个额外的秒,并导致高CPU负载。快速修复方法是(以root身份):

$ /etc/init.d/ntpd stop
$ date -s "`date`"
$ /etc/init.d/ntpd start

23
既然原帖是三年前的,我怀疑它不是原帖作者问题的原因。但它却是我问题的原因,并且现在救了我-所以谢谢!更多信息:http://blog.mozilla.org/it/2012/06/30/mysql-and-the-leap-second-high-cpu-and-the-fix/ - Russell G
5
在Ubuntu 12.04上,我遇到了同样的问题和解决方案。解决步骤略有不同: service ntp stop && date -s "date" && service ntp start MySQL的CPU使用率立即从50%-100%降至0%-1%。 - David Laing
3
即使不是出于某种特定原因,这个操作是否可以安全地运行,仅仅为了确认一下? - Muhammad Gelbana
2
2015年7月1日 - 我刚刚在一台正在运行Amazon Linux的当前AWS EC2服务器上经历了这个闰秒错误。在此配置中使用sudo service ntpd stop. - Matt van Andel
1
这个解决方案非常好,给你点赞。我的MySQL运行了几个月,占用50-60%的CPU,但是应用了这个解决方案后,它现在只占用0.0-0.3%的CPU,这才是正常的状态。非常感谢。 - zeeshan
显示剩余21条评论

40
如果这台服务器对外可见,值得检查是否有大量的来自外部世界的连接请求(即试图攻击它的人)。

1
不确定为什么会有匿名的踩,考虑到这在过去曾经是一些系统出现问题的原因。 - Rowland Shaw
2
我认为这个down vote是因为让MySQL对外可见不是一个好主意。 - MikeKulls
10
不,这不是一个好主意,因为它将成为很多人试图尝试进入的目标,这将导致高CPU负载-因此我的回答是可能的原因之一。 - Rowland Shaw
17
有人只是点个踩就走,我很讨厌这种行为! - Muhammad Gelbana
1
+1 因为这绝对是 MySQL CPU 使用率高的合理原因,任何需要此答案的人都确实需要这些信息! - Chris Browne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接