最近在本身购买的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上有大量的闲置链接。服务器
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)
若是上述问题仍是不能解决的话,可使用如下脚本定时杀掉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 &