如何处理MySQL常常出现CPU占用率达到99%

如何处理MySQL常常出现CPU占用率达到99%

状况说明:

最近在本身购买的linux服务器上捣鼓了一个小项目,按理说不存在CPU占用率会达到100%的状况,但事实就是常常出现。mysql

而后,我第一反应是“卧槽,被人当矿机了?”,而后一顿查询操做后,发现并无被人捣鼓,问题出如今mysql上,MySQL的CPU占用率达到了100%;这是我就很纳闷了,这么小个程序,不该该啊。而后就开始了排查。linux

查询了下sql进程,发现:sql

mysql> show processlist;
+-----+------+----------------------+-------------+---------+------+-------+------------------+
| Id  | User | Host                 | db          | Command | Time | State | Info             |
+-----+------+----------------------+-------------+---------+------+-------+------------------+
|   8 | root | 182.150.55.136:64138 | itresources | Sleep   | 16686 |       | NULL             |
|   18 | root | 182.150.55.136:65138 | itresources | Sleep   | 12886 |       | NULL             |
|   22 | root | 182.150.55.136:66138 | itresources | Sleep   | 14486 |       | NULL             |
|   11 | root | 182.150.55.136:67138 | itresources | Sleep   | 1116 |       | NULL             |
| 206 | root | localhost            | NULL        | Query   |    0 | NULL  | show processlist |
+-----+------+----------------------+-------------+---------+------+-------+------------------+
2 rows in set (0.00 sec)

发现MySQL上有大量的闲置链接。服务器

解决措施1:

MySQL服务器所支持的最大链接数是有上限的,由于每一个链接的创建都会消耗内存,所以咱们但愿客户端在链接到MySQL Server处理完相应的操做后,应该断开链接并释放占用的内存。若是你的MySQL Server有大量的闲置链接,他们不只会白白消耗内存,并且若是链接一直在累加而不断开,最终确定会达到MySQL Server的链接上限数,这会报'too many connections'的错误。对于wait_timeout的值设定,应该根据系统的运行状况来判断。在系统运行一段时间后,能够经过show processlist命令查看当前系统的链接状态,若是发现有大量的sleep状态的链接进程,则说明该参数设置的过大,能够进行适当的调整小些。优化

Mysql> show variables like '%timeout%';

+-----------------------------+----------+
| Variable_name              | Value    |
+-----------------------------+----------+
| connect_timeout            | 10      | 
| delayed_insert_timeout      | 300      | 
| innodb_flush_log_at_timeout | 1        | 
| innodb_lock_wait_timeout    | 50      | 
| innodb_rollback_on_timeout  | OFF      | 
| interactive_timeout        | 28800    | 
| lock_wait_timeout          | 31536000 | 
| net_read_timeout            | 30      | 
| net_write_timeout          | 60      | 
| slave_net_timeout          | 3600    | 
| wait_timeout                | 28800    | 
+-----------------------------+----------+

11 rows in set (0.00 sec)

经查询发现原来mysql没有进行过优化,仍是原来的默认值:28800(即8个小时)日志

编辑 /etc/my.cnf 文件,在mysqld 下 新增 timeout参数,设置为120秒,以下:code

【mysqld】
wait_timeout=120
interactive_timeout=120

注意:要同时设置interactive_timeout和wait_timeout才会生效。进程

最后重启一下mysql 生效 便可!内存

mysql> show variables like '%timeout%';
+----------------------------+----------+
| Variable_name              | Value    |
+----------------------------+----------+
| connect_timeout            | 10       |
| delayed_insert_timeout     | 300      |
| innodb_lock_wait_timeout   | 50       |
| innodb_rollback_on_timeout | OFF      |
| interactive_timeout        | 120      |
| lock_wait_timeout          | 31536000 |
| net_read_timeout           | 30       |
| net_write_timeout          | 60       |
| slave_net_timeout          | 3600     |
| wait_timeout               | 120      |
+----------------------------+----------+
10 rows in set (0.00 sec)

解决措施2:

若是上述问题仍是不能解决的话,可使用如下脚本定时杀掉CPU占用率95%以上的进程ssl

#!/bin/sh
# qiyulin to monitor used CPU
record=0
while true;
do
cpu=$(top -b -n1 | grep 'mysql' | head -1 | awk '{print $9}')
pid=$(top -b -n1 | grep 'mysql' | head -1 | awk '{print $1}')
#cpu check
result=${cpu/.*}
if [[ $record == $pid ]];then kill -9 $pid;echo "$pid was killed";fi
if [[ $result > 95 || $result == 100 ]];then let record=${pid};else let record=0;fi
#echo
echo `date +%F" "%H:%M:%S`+" cpu:$result% record pid:$record pid:$pid"
sleep 60
done

使用以下命令启动,能够保证该脚本的持续运行,而且能在CPU.out文件中看到日志记录:

nohup sh ./checkCPU.sh > CPU.out &
相关文章
相关标签/搜索