关于mysql:排查Mysql突然变慢的一次过程

44次阅读

共计 1426 个字符,预计需要花费 4 分钟才能阅读完成。

排查 Mysql 忽然变慢的一次过程

本文源地址:排查 Mysql 忽然变慢的一次过程

上周客户说零碎忽然变得很慢,而且时不时的蹦出一个 404500,弄得真的是很没面子,而凑巧出问题的时候正在深圳出差,所以始终没有工夫
看问题,始终到明天,才算是把问题起因找到。


定位问题

刚开始失去是零碎慢的反馈,没有将问题点定位到数据库上,查了半天服务是否失常(因为之前有一次 Dubbo 内存透露)。

在将应用服务日志查看了一遍后,没有发现任何异样,只是打了几个正告的日志。

于是又查看了业务运行时的日志,看到日志都提醒了一个 Lock wait timeout exceeded; try restarting transaction 的异样。

这时还是没有将重心放到数据库上,认为是代码的起因,导致事务始终没有提交。

从新将代码审阅了一遍,感觉应该不是代码逻辑的问题,而这个时候,Lock wait timeout exceeded; try restarting transaction 这个异样的日志越来越多。

认为是数据库层面出了问题,开始排查数据库。


寻找起因

因为咱们的数据库不是用的 云 RDS 版本 ,是在一台 8 核 32G 的 AWS 上的装置版本。

应用 top 命令,查看到 Mysql 占用的 CPU 使用率高达 90% 左右。

心里一慌,感觉不妙,这样子高负载的 CPU 使用率,搞不好服务器都要宕掉。

于是拿出了仅有的一点 Mysql 基本知识,基本上这次只应用到了上面几个语句:

  • 查看以后 Mysql 所有的过程

show processlist;

  • 查看 Mysql 的最大缓存

show global variables like "global max_allowed_packet"

  • 查看以后正在进行的事务

select * from information_schema.INNODB_TRX

  • 查看以后 Mysql 的连接数

show status like 'thread%'


解决

依照下面的几个语句,一步一步跟踪定位下来。

show processlist; 下来,咱们就能够查看出以后所有的过程,并且失去最耗时的过程。

在以后数据库中,看到处于 Sleep 状态的 SQL 十分多,而这也是占用 CPU 过高的重大起因,休眠线程太多,于是配置了一个 wait_time_out 为 600 秒的一个解决方案。

为什么配置 600 秒,因为咱们利用超时工夫配置的最大工夫就是 600 秒,10 分钟,这里的配置须要依据业务来具体配置。

select * from information_schema.INNODB_TRX

执行这个语句,看到 Mysql 中大部分处于 Lock 的 SQL 是一条 update 的 SQL,而且还有一个单条件的 SQL,查问竟然耗时 4 分钟,很是诧异。

于是查看了这张表。

刚一关上构造,差点没忍住口吐芳香,竟然一个索引都没有,数据量超过 300W,没有索引查问基本上都要 4 分钟往上走。

于是筹备加上索引,在一阵漫长的期待中,索引终于加上去了。

show status like 'thread%'

索引加上去了之后,查看了一下以后 Mysql 的连接数,仿佛没有之前那么高了,预计是挤压的太多。

而后又查看了下服务器的 CPU 占用率,这次好了一点,从 1% 到 80% 来回跳动,没有呈现 90& 那么高的频率。


总结

Mysql 作为应用频率十分高的数据库,对于它的 SQL 调优真的是一门技术活,而且我的项目中的一些 SQL 看的也是想吐,这种调优起来真的难上加难。

其实 information_schema 这个数据库,外面的 Mysql 日志看起来比业务日志悦目的很多。

正文完
 0