我正在寻找一个经过充分testing的bash脚本(或其他解决scheme),以避免max_connection被耗尽。 我知道这是对付症状,但真的需要这样的脚本作为短期解决scheme。
检查percona工具包中的 pt-kill命令。
和..开始监测你的系统 – munin , 仙人掌与更好的仙人掌模板为MySQL ,任何事情,让你知道发生了什么事情。 loggingmysql缓慢的查询也是一个好主意。
如果你的MySQL 5.1中的进程列表在INFORMATION_SCHEMA中,那么你可以这样做,从mysql客户端中批量生成KILL QUERY命令,查询运行时间超过20分钟(1200秒):
SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= 1200\G
您可以对INFO字段执行WHERE子句以查找特定的查询,针对长时间运行的查询的TIME字段或针对特定数据库的DB字段。
如果你是root @ localhost,你应该拥有完整的权限来运行它,如下所示
SECONDS_TOO_LONG=1200 KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}" mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword
你可以这样crontab:
SECONDS_TOO_LONG=1200 QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"` if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ] then KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}" mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword fi
这是另一个变化:
SECONDS_TOO_LONG=1200 QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"` if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ] then KILLPROC_SQLSTMT="SELECT CONCAT('KILL QUERY ',id,';') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}" mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" > /tmp/kill_log_queries.sql mysql -uroot -ppassword < /tmp/kill_log_queries.sql fi
顺便说一句,你没有指定一个myDB,因为我明确地从information_schema.processlist读取一个完全合格的表名。
这是你应该看到的一个示范。 对于这个例子,我将回显所有时间大于20000秒的进程的KILL命令:
[root@***** ~]# mysql `lwdba_connect` -ANe"SELECT GROUP_CONCAT('KILL ',id,'; ' SEPARATOR ' ') FROM information_schema.processlist WHERE time > 25000 AND user<>'system user';" +----------------------------------------------------+ | KILL 180186; KILL 180141; KILL 176419; KILL 3; | +----------------------------------------------------+ [root@***** ~]#
过去5年来我一直在做这个技术。 实际上,去年我把这个答案提交给了DBA StackExchange,并且被接受了 。
我在这里find了下面的代码片断:
更新 2013-01-14:有一个匿名提示,这是潜在的危险,也可以杀死复制过程。 所以请自担风险:
mysql -e 'show processlist\G' |\ egrep -b5 'Time: [0-9]{2,}' |\ grep 'Id:' |\ cut -d':' -f2 |\ sed 's/^ //' |\ while read id do mysql -e "kill $id;" done