【问题标题】:How do I kill all the processes in Mysql "show processlist"?如何杀死Mysql“show processlist”中的所有进程?
【发布时间】:2010-12-26 14:33:02
【问题描述】:

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

【问题讨论】:

  • 你也可以重启mysqld,例如sudo service mysqld restart

标签: mysql database


【解决方案1】:

群杀操作节省时间。在 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;

Reference

---------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")

【讨论】:

  • 请记得参考出处:mysqlperformanceblog.com/2009/05/21/…
  • @ArtemGoutsoul 但我不记得我提到过这个网站。这是我自己的趋势。
  • @JanusTroelsen 但我的回答是在 12 年 3 年后
  • 是否可以在没有文件的情况下使用 linux 管道来做到这一点?
  • @ShankarDamodaran SURE
【解决方案2】:

你需要一一杀掉,MySQL没有海量杀戮命令。您可以使用任何语言编写脚本,例如在 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);
  }
}

【讨论】:

  • 这是个好主意。让我尝试将其转换为 cron 上的 shell 脚本...!
  • 壳牌for i in {994..1145}; do mysql -uroot -p123456 -e "kill $i" ; done
  • mysql -u -p -e "显示进程列表;" | grep 睡眠 | awk '{打印 $1}' |一边读线;执行 mysql -u -p -e "kill $LINE";完成
【解决方案3】:

我还搜索了如何通过 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 的最后一次调用将执行传递的命令。

您可以在 awk 命令之前运行 grep 来过滤特定的数据库名称。

【讨论】:

    【解决方案4】:

    仅适用于 mariaDB

    没有比这更简单的了,在mysql提示符下执行即可。

    kill USER username;
    

    它将杀死提供的用户名下的所有进程。因为大多数人出于所有目的都使用同一个用户,所以它有效!

    我在 MariaDB 上测试过,不确定 mysql。

    【讨论】:

    • 这存在于哪个版本的 MySQL 中?我没有在MySQL 5.7 reference 中看到它;没有证据表明有可能被用户杀死:KILL [CONNECTION | QUERY] processlist_id。我在 MySQL 5.6.34 中尝试过您的查询,它被认为是语法错误。
    • 我在 MySQL 5.6.34 提示符下试过这个:mysql&gt; kill user root; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'root' at line 1 可能你的答案是 MariaDB 特有的特性。
    • 这不适用于 Mysql。请在发布与其他数据库系统相关的建议之前阅读...
    【解决方案5】:

    或者...在外壳中...

    service mysql restart
    

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

    【讨论】:

    • 这是一个非常糟糕的主意...特别是如果您在内存上设置了表引擎,则会导致所有数据丢失...或者如果您使用 innodb 引擎类型,则会重做重启时的所有索引
    • 它还会杀死所有数据库上的所有进程
    【解决方案6】:

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

    -- 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;
    

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

    【讨论】:

    【解决方案7】:

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

    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 ;
    

    可以用SELECTs运行,显示前后进程如下:

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

    【讨论】:

      【解决方案8】:

      如果您没有 information_schema:

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

      【讨论】:

      • 我相信第二行应该是mysql &lt; /tmp/kill.txt。而且我认为在大多数情况下你会发现你需要指定运行mysql命令的用户和密码,所以它会是mysql -u root -p &lt; /tmp/kill.txt
      【解决方案9】:

      杀死所有选择查询

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

      【讨论】:

        【解决方案10】:

        这个片段对我有用(MySQL 服务器 5.5)杀死所有 MySQL 进程:

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

        【讨论】:

          【解决方案11】:

          我们可以通过 MySQL Workbench 来完成。只需执行此操作:

          kill id;
          

          例子:

          kill 13412
          

          这将删除它。

          【讨论】:

          • 这听起来更好的答案,因为上面没有提到语言。
          【解决方案12】:

          我会结合 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
          

          【讨论】:

            【解决方案13】:

            这是一个您可以在不依赖操作系统的情况下执行的解决方案:

            第 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');

            【讨论】:

              【解决方案14】:
              mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}
              

              【讨论】:

              • 你好。不确定您是机器人、社区还是人类,但无论如何,如果您添加一些文字来解释这行代码发生了什么以及它如何解决手头的问题,那就太好了?
              • 添加了 -u 和 -p 以授予用户访问权限...工作很好!
              【解决方案15】:

              以管理员身份登录Mysql:

               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)
              

              【讨论】:

              • 这不是问题的答案。在这里,您正在杀死一个进程,而问题是如何一次杀死进程。
              • @badbod99 我最终在这里寻找如何杀死一个 mysql 进程,这个答案对我有帮助,所以我投了赞成票。
              【解决方案16】:

              对于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()
              

              【讨论】:

                【解决方案17】:

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

                【讨论】:

                  【解决方案18】:
                  #! /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;
                  

                  【讨论】:

                    【解决方案19】:

                    有时我有一些无法杀死的僵尸 mysql 进程(使用 MAMP Pro)。

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

                    ps -ax | grep mysql
                    

                    接下来将它们中的每一个都杀死(将 processId 替换为上一个命令结果中的第一列):

                    kill -9 processId
                    

                    【讨论】:

                      【解决方案20】:

                      以下内容对我很有用:

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

                      【讨论】:

                        【解决方案21】:

                        我使用命令flush tables 杀死了所有非活动连接,这实际上是大规模问题。

                        【讨论】:

                        • 不起作用。刷新表但保持睡眠连接处于活动状态
                        【解决方案22】:

                        如果正在运行的进程不是你的,Kill 不起作用。我合并了其中一些解决方案并对其进行了扩展以创建一个更简单的解决方案(至少对我而言)。

                        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
                        

                        【讨论】:

                          【解决方案23】:

                          如果你使用的是 laravel,那么这是给你的:

                          $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;

                          【讨论】:

                            【解决方案24】:

                            查询 1 select concat('KILL ',id,';') from information_schema.processlist where user='username' into outfile '/tmp/a.txt';

                            查询 2 源 a.txt

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

                            【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2019-01-07
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-02-06
                            • 1970-01-01
                            相关资源
                            最近更新 更多