Mysql数据库CPU跑满相关问题排查

大部分mysql引起的cpu跑满情况都是由与SQL写的有问题或者锁无法及时释放导致的。

美好的一天总是从一份丰富营养的早餐开始…….偏题了,糟心的一天总是从生产的各种问题开始…

晚上业务高峰期突然接到通知访问缓慢,甚至出现异常报错情况,经过日志分析,凭借经验排查发现2台读写分离数据库的CPU都以及飙升到99%,基本上处于不可用状态,可以直观感受下:

数据库CPU使用率

出现CPU占满,一般可能会有以下几种情况:

1.操作数据库并发量超高,已经超出了现有能支持的水平

2.操作SQL写的有问题,常见于多表联查,甚至需要复杂计算才能得出的结果

3.写入数据库表的所一直没释放(有可能也是sql问题,也可能是外部问题)

而根据经验来看第2种情况比较常见,因此先按第2种来着手分析解决

1.先看看目前有哪些进程

show processlist 

上面的信息包括ID,操作数据库用户,来源IP,持续时间,执行的SQL语句

我们大部分时候都需要重点关注SQL执行持续时间,比如上图中红色框框的SQL,可以看到SQL已经已经持续了9分多钟,这种SQL执行较多时还会直接导致大量SQL无法回应,占用CPU资源处理SQL(这里要记录下对应的ID)。

如果还不确定是不是真的由与这些SQL引起的,可以再根据当前正在执行的事务看看

2.  select * from information_schema.INNODB_TRX

INNODB_TRX

上图可以看出正在运行未提交的事务,根据开始时间可推算出距离当前时间,事务持续了多久,一般超出3s的话都应该是有问题的。

3.既然找出大概问题,那么可以先采用Kill 命令来结束有异常的SQL

登入sql控制台,输入 :Kill threadId(执行任务ID) ,如 Kill 36894806 ;会发现结束进程后看监控盘数据,发现cpu过几分钟马上就下来了

当然,以上临时解决问题的方法,造成该问题的根本原因还是SQL查询写的有问题,嵌套查询,多表联查,在数据量大的情况下持续时间会比较久。

常规的优化手段:

1.根据业务进行SQL拆分,尽量关联少的表

2.对关键常用的条件进行联合索引,加快查询速度(优化的重点方向)

3.调整一下数据库链接无响应的最大超时时间 wait_timeout ,该参数默认为8小时,可以调整到100s之内,超出时间未响应,自动放弃本次链接。

4.如果发现并发数满了,除了上面的优化以外可以再新增一台读库来应对高并发操作(该方案是在SQL优化后无法进行深层次优化的基础上,或者有大量资金支持除外)