如何杀死 Mysql“ show processlist”中的所有进程?

因为我在那里看到了很多进程,“时间”列显示了所有进程的大值。

450258 次浏览

你需要一个一个地杀死他们,MySQL 没有任何大规模的 kill 命令。您可以使用任何语言编写脚本,例如,在 PHP 中,您可以使用如下内容:

$result = mysql_query("SHOW FULL PROCESSLIST");
while ($row=mysql_fetch_array($result)) {
$process_id=$row["Id"];
if ($row["Time"] > 200 ) {
$sql="KILL $process_id";
mysql_query($sql);
}
}

大规模杀伤 操作节省时间,在 MySql 中完成:

运行这些命令

mysql> select concat('KILL ',id,';') from information_schema.processlist
where user='root' and time > 200 into outfile '/tmp/a.txt';


mysql> source /tmp/a.txt;

参考文献

---------edit------------

如果不想存储在文件中,则存储在 variable

只需在命令提示符中运行

> out1=$(mysql -B test -uroot -proot --disable-column-names  -e "select concat('KILL ',id,';') from information_schema.processlist where user='root' and time > 200;")


> out2= $(mysql -B test -uroot -proot --disable-column-names  -e "$out1")

我还搜索了如何通过 MySQL 解析命令 SHOW PROCESSLIST,并以 Shell 中的一行程序结束:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • Mysqladmin processlist 将打印具有线程 id 的表;
  • Awk 将仅解析第二列中的数字(线程 id)并生成 MySQL KILL 命令;
  • 最后,对 Mysql的最后一次调用将执行传递的命令。

可以在 命令之前运行 Grep来筛选特定的数据库名称。

如果没有 information _ schema:

mysql -e "show full processlist" | cut -f1 | sed -e 's/^/kill /' | sed -e 's/$/;/' ;  > /tmp/kill.txt
mysql> . /tmp/kill.txt

以管理员身份登录 Myql:

 mysql -uroot -ppassword;

然后运行命令:

mysql> show processlist;

你会得到如下内容:

+----+-------------+--------------------+----------+---------+------+-------+------------------+
| Id | User        | Host               | db       | Command | Time | State | Info             |
+----+-------------+--------------------+----------+---------+------+-------+------------------+
| 49 | application | 192.168.44.1:51718 | XXXXXXXX | Sleep   |  183 |       | NULL             ||
| 55 | application | 192.168.44.1:51769 | XXXXXXXX | Sleep   |  148 |       | NULL             |
| 56 | application | 192.168.44.1:51770 | XXXXXXXX | Sleep   |  148 |       | NULL             |
| 57 | application | 192.168.44.1:51771 | XXXXXXXX | Sleep   |  148 |       | NULL             |
| 58 | application | 192.168.44.1:51968 | XXXXXXXX | Sleep   |   11 |       | NULL             |
| 59 | root        | localhost          | NULL     | Query   |    0 | NULL  | show processlist |
+----+-------------+--------------------+----------+---------+------+-------+------------------+

您将看到不同连接的完整细节。现在您可以按照以下步骤终止睡眠连接:

mysql> kill 52;
Query OK, 0 rows affected (0.00 sec)

终止所有选择的查询

select concat('KILL ',id,';')
from information_schema.processlist
where user='root'
and INFO like 'SELECT%' into outfile '/tmp/a.txt';
source /tmp/a.txt;

这里有一个不需要依赖操作系统就可以执行的解决方案:

步骤1: 创建一个存储过程。

DROP PROCEDURE IF EXISTS  kill_user_processes$$


CREATE PROCEDURE `kill_user_processes`(
IN user_to_kill VARCHAR(255)
)
READS SQL DATA
BEGIN


DECLARE name_val VARCHAR(255);
DECLARE no_more_rows BOOLEAN;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE num_rows INT DEFAULT 0;


DECLARE friends_cur CURSOR FOR
SELECT CONCAT('KILL ',id,';') FROM information_schema.processlist WHERE USER=user_to_kill;


DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows = TRUE;


OPEN friends_cur;
SELECT FOUND_ROWS() INTO num_rows;


the_loop: LOOP


FETCH  friends_cur
INTO   name_val;


IF no_more_rows THEN
CLOSE friends_cur;
LEAVE the_loop;
END IF;




SET @s = name_val;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


SELECT name_val;


SET loop_cntr = loop_cntr + 1;


END LOOP the_loop;


SELECT num_rows, loop_cntr;


END $$
DELIMITER ;

步骤2: 调用存储过程,给出要终止其进程的数据库用户的名称。如果愿意,您可以重写存储过程,以根据其他一些条件进行筛选。

打电话给 kill_user_processes('devdba');

一个简单的方法是重新启动 mysql 服务器. 。 在 windows Run 中打开“ services.msc”,从列表中选择 Mysql。右击并停止服务。然后重新启动,除了一个进程(默认的保留连接)之外,所有进程都将被终止

或者,在贝壳里。

service mysql restart

是的,我知道,我很懒,但它也可以很方便。

mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}

我最近需要这样做,我想出了这个

-- GROUP_CONCAT turns all the rows into 1
-- @q:= stores all the kill commands to a variable
select @q:=GROUP_CONCAT(CONCAT('KILL ',ID) SEPARATOR ';')
FROM information_schema.processlist
-- If you don't need it, you can remove the WHERE command altogether
WHERE user = 'user';
-- Creates statement and execute it
PREPARE stmt FROM @q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

这样,您就不需要存储文件并使用单个命令运行所有查询。

问题1 从 information _ schema. processlist 中选择 concat (‘ KILL’,id,’;’) ,其中 user = ‘ username’进入 outfile’/tmp/a.txt’;

问题2 来源 A.txt

这将使您能够根据特定用户杀死 show processlist 中的所有查询。

#! /bin/bash
if [ $# != "1" ];then
echo "Not enough arguments.";
echo "Usage: killQueryByDB.sh <db_name>";
exit;
fi;


DB=${1};
for i in `mysql -u <user> -h localhost ${DB} -p<password> -e "show processlist" | sed 's/\(^[0-9]*\).*/\1/'`; do
echo "Killing query ${i}";
mysql -u <user> -h localhost ${DB} -p<password> -e "kill query ${i}";
done;

这段代码对我(MySQL server 5.5)来说非常有用,可以杀死所有的 MySQL 进程:

mysql -e "show full processlist;" -ss | awk '{print "KILL "$1";"}'| mysql

下面将创建一个简单的存储过程,该过程使用游标逐个杀死除当前正在使用的进程之外的所有进程:

DROP PROCEDURE IF EXISTS kill_other_processes;


DELIMITER $$


CREATE PROCEDURE kill_other_processes()
BEGIN
DECLARE finished INT DEFAULT 0;
DECLARE proc_id INT;
DECLARE proc_id_cursor CURSOR FOR SELECT id FROM information_schema.processlist;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;


OPEN proc_id_cursor;
proc_id_cursor_loop: LOOP
FETCH proc_id_cursor INTO proc_id;


IF finished = 1 THEN
LEAVE proc_id_cursor_loop;
END IF;


IF proc_id <> CONNECTION_ID() THEN
KILL proc_id;
END IF;


END LOOP proc_id_cursor_loop;
CLOSE proc_id_cursor;
END$$


DELIMITER ;

它可以与 SELECT一起运行,以显示以下前后的进程:

SELECT * FROM information_schema.processlist;
CALL kill_other_processes();
SELECT * FROM information_schema.processlist;

只为 MariaDB

没有比这个更简单的了,只需要在 mysql 提示符中执行它。

kill USER username;

它将终止所提供用户名下的所有进程。因为大多数人使用同一个用户的所有目的,它的工作!

我在 MariaDB 上测试过这个,但是对 mysql 不太确定。

有时我有一些僵尸 mysql 进程,不能被杀死(使用 MAMP 专业版)。

首先获取所有 mysql 进程的列表:

ps -ax | grep mysql

接下来用下面的命令杀死每一个元素(用前一个命令 result 中的第一列替换 processId) :

kill -9 processId

下面的方法对我很有效:

echo "show processlist" | mysql | grep -v ^Id | awk '{print $1}' | xargs -i echo "KILL {}; | mysql"

我使用命令 flush tables杀死所有不活跃的连接,其中实际上质量问题。

我们可以通过 MySQL 工作台来实现:

kill id;

例如:

kill 13412

这样就能移除了。

对于 python 语言,您可以这样做

import pymysql


connection = pymysql.connect(host='localhost',
user='root',
db='mysql',
cursorclass=pymysql.cursors.DictCursor)


with connection.cursor() as cursor:
cursor.execute('SHOW PROCESSLIST')
for item in cursor.fetchall():
if item.get('Time') > 200:
_id = item.get('Id')
print('kill %s' % item)
cursor.execute('kill %s', _id)
connection.close()

我会把 bash 和 mysql 结合起来:

for i in $(mysql -Ne "select id from information_schema.processlist where user like 'foo%user' and time > 300;"); do
mysql -e "kill ${i}"
done

如果你正在使用幼虫,那么这是为你准备的:

$query = "SHOW FULL PROCESSLIST";
$results = DB::select(DB::raw($query));


foreach($results as $result){
if($result->Command == "Sleep"){
$sql="KILL ". $result->Id;
DB::select(DB::raw($sql));
}
}

当然,您应该在命名空间之后使用这个 use Illuminate\Support\Facades\DB;

如果正在运行的进程不是您的,则杀死不起作用。我合并了其中的一些解决方案,并扩展它们以创建一个更简单的解决方案(至少对我来说)。

m=mysql -p $password -h $host -u$user #you can also inline it of course
for i in `$m -e "show processlist" | awk '/$anySearchString/ {print $1}'`; do $m -e "call mysql.rds_kill($i);"; done