我有一个使用大数据库的旧网站,现在我不想升级它。问题是mysql数据库有一些查询需要很长时间,当大约4000名在线用户的高流量导致mysql达到600%-800%时,我不得不从WHM手动重新启动mysql服务器。
我想使用cronjobsimpleshell脚本每10秒读取一次mysql进程列表,如果任何进程时间超过10秒,它就会杀死这个进程。
这是我为完成这样的任务找到的查询:
mysql -e 'SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST where time>10 and command<>"Sleep"'
我认为要获得要杀死的进程ID,我应该使用:
mysql -e 'SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST where time>10 and command<>"Sleep"'
这样的输出:
+------+
| ID |
+------+
| 1095 |
| 1094 |
| 1081 |
| 1079 |
| 1078 |
| 1074 |
| 1040 |
| 1038 |
+------+
现在我有了这个输出表,我只需要将这个任务封装在shell脚本中,以解析这些进程ID并杀死它们。
您可以将输出保存在数组中,并使用grep只过滤数字。
mapfile -t array < <(mysql .... | grep -Ewo '[[:digit:]]+')
另一种选择是使用while read loop
while read -r digits; do
if [[ $digits =~ .*([[:digit:]]{4}).* ]]; then
array+=("${BASH_REMATCH[1]}")
fi
done < <(mysql ....)
现在"${array[@]}"
只有所有的数字值。
杀死它,检查它是否正在运行,一个接一个地循环,等等
以下是我为特定数据库用户"db_user"想出的方法,以避免备份等系统长过程:
#!/bin/bash
for i in $(mysql -Ne 'select id from information_schema.processlist where USER="db_user" and time>20 and command<>"Sleep";'); do
mysql -e "kill ${i}"
done
将其保存为mysqlkill_high_processes.sh,并将其添加到根用户cron中以每分钟运行一次。