web-dev-qa-db-fra.com

Comment puis-je tuer tous les processus dans Mysql "show processlist"?

Parce que je vois beaucoup de processus là-bas, et que la colonne "heure" indique de grandes valeurs pour chacun d'entre eux.

103
TIMEX

Vous devez les tuer un par un, MySQL n’a pas de commande de destruction massive. Vous pouvez l'écrire dans n'importe quel langage. Par exemple, dans PHP, vous pouvez utiliser quelque chose comme:

$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);
  }
}
96
Michal Čihař

L’assassinat en masse permet de gagner du temps. Faites-le dans MySql lui-même:

Exécuter ces commandes

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;

Référence

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

si vous ne voulez pas stocker dans un fichier, stockez-le dans une variable

Il suffit de lancer l'invite de commande

> 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")
190
Angelin Nadar

J'ai également cherché comment analyser dans MySQL la commande SHOW PROCESSLIST et j'ai terminé avec un one-liner dans un shell:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • mysqladmin processlist affichera une table avec les identifiants de thread;
  • awk analysera dans la deuxième colonne uniquement les nombres (identificateurs de thread) et générera des commandes MySQL KILL;
  • et enfin le dernier appel à mysql exécutera les commandes passées.

Vous pouvez exécuter grep avant la commande awk pour filtrer un nom de base de données particulier.

16
m8t

Ou ... dans Shell ...

service mysql restart

Ouais, je sais, je suis paresseux, mais ça peut être pratique aussi.

12
EcchiOli

Cela ne devient pas plus simple, exécutez-le simplement dans l'invite mysql.

kill USER username;

Il va tuer tous les processus sous le nom d'utilisateur fourni. parce que la plupart des gens utilisent le même utilisateur à toutes fins utiles, cela fonctionne!

J'ai testé cela sur MariaDB pas sûr de mysql.

10
Maulik Gangani

Si vous n'avez pas information_schema:

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

5
mikesl

Ce qui suit va créer une procédure stockée simple qui utilise un curseur pour tuer tous les processus un par un sauf le processus en cours d'utilisation:

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 ;

Il peut être exécuté avec SELECTs pour afficher les processus avant et après comme suit:

SELECT * FROM information_schema.processlist;
CALL kill_other_processes();
SELECT * FROM information_schema.processlist;
4
Steve Chambers

connectez-vous à Mysql en tant qu'administrateur:

 mysql -uroot -ppassword;

Et que exécuter la commande:

mysql> show processlist;

Vous obtiendrez quelque chose comme ci-dessous:

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

Vous verrez les détails complets des différentes connexions. Maintenant, vous pouvez tuer la connexion en sommeil comme ci-dessous:

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

TUE TOUTES LES QUERIES 

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

Voici une solution que vous pouvez exécuter sans utiliser le système d'exploitation:

ÉTAPE 1: Créez une procédure stockée. 

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 ;

ÉTAPE 2: Appelez la procédure stockée en lui donnant le nom d’un utilisateur de la base de données dont vous souhaitez tuer les processus. Vous pouvez réécrire la procédure stockée pour filtrer d'autres critères si vous le souhaitez.

CALL kill_user_processes('devdba');

3
Dan Spiegel

Cette capture a fonctionné pour moi (serveur MySQL 5.5) pour tuer tous les processus MySQL: 

mysql -e "show full processlist;" -ss | awk '{print "KILL "$1";"}'| mysql
3
Fedir RYKHTIK
mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}
2
user3721740

Nous pouvons le faire avec MySQL Workbench. Il suffit d'exécuter ceci:

kill id;

Exemple:

kill 13412

Cela va l'enlever. 

2
Aroon

J'ai récemment eu besoin de faire cela et je suis venu avec cette

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

De cette façon, vous n'avez pas besoin de stocker dans un fichier et d'exécuter toutes les requêtes avec une seule commande.

2
Iberê

Je combinerais bash et 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
1
wiebel

J'ai utilisé la commande flush tables pour tuer toutes les connexions inactives qui étaient en réalité le problème de masse.

0
Meltzer
#! /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;

Parfois, j'ai des processus mysql zombies qui ne peuvent pas être tués (avec MAMP Pro). 

Commencez par obtenir une liste de tous les processus mysql:

ps -ax | grep mysql

Tuez ensuite chacun d’entre eux avec (remplacez processId par la première colonne du résultat de la commande précédente):

kill -9 processId
0
Nico Prat

Si vous utilisez laravel, ceci est pour vous: 

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

Bien sûr, vous devriez utiliser ce use Illuminate\Support\Facades\DB; après votre espace de noms. 

0
Ziaur Rahman

pour le langage python, vous pouvez faire comme ça

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()
0
BohanZhang

Ce qui suit a bien fonctionné pour moi:

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

Un moyen simple serait de redémarrer le serveur mysql .. Ouvrez "services.msc" dans Windows, cliquez sur Exécuter, sélectionnez Mysql dans la liste. Faites un clic droit et arrêtez le service. Ensuite, redémarrez et tous les processus auraient été tués sauf celui (la connexion réservée par défaut)

0
shashi009