Comment tuer tous les processus dans Mysql «show processlist»?

121

Parce que je vois beaucoup de processus là-bas, et la colonne «temps» montre de grandes valeurs pour chacun d'eux.

TIMEX
la source
Vous pouvez également redémarrer mysqld, par exemplesudo service mysqld restart
philfreo

Réponses:

108

Vous devez les tuer un par un, MySQL n'a pas de commande kill massive. Vous pouvez le script dans n'importe quel langage, par exemple en 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);
  }
}
Michal Čihař
la source
C'est une bonne idée. Laisse-moi essayer de le convertir en script shell sur un cron ...!
M. Faraz
4
Shellfor i in {994..1145}; do mysql -uroot -p123456 -e "kill $i" ; done
zhuguowei
mysql -u -p -e "afficher la liste des processus;" | grep Sleep | awk '{imprimer $ 1}' | tout en lisant LINE; faire mysql -u -p -e "tuer $ LINE"; done
user3770797
213

L' opération de massacre fait gagner du temps. Faites-le dans MySql lui-même:

Exécutez 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 souhaitez pas stocker dans un fichier, stockez dans un variable

Exécutez simplement votre 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")
Angelin Nadar
la source
13
N'oubliez pas de vous référer à la source: mysqlperformanceblog.com/2009/05/21/…
Artem Goutsoul
2
@ArtemGoutsoul mais je ne me souviens pas avoir fait référence à ce site. C'est ma propre tendance à le faire.
Angelin Nadar
@JanusTroelsen mais ma réponse est après 3 ans '12
Angelin Nadar
1
@Angelin Nadar Merci!
Silver Light
1
@ShankarDamodaran SURE
Angelin Nadar
16

J'ai également cherché comment analyser via MySQL la commande SHOW PROCESSLIST et je me suis terminé par une ligne unique 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 à partir de la deuxième colonne uniquement les nombres (identifiants 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.

m8t
la source
13

Ou ... en coquille ...

service mysql restart

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

EcchiOli
la source
10
c'est une très mauvaise idée ... en particulier si vous avez le moteur de table en mémoire, car toutes les données seront perdues ... ou si vous utilisez le type de moteur innodb, car il refera tous les index au redémarrage
HellBaby
8
En outre, il tue tous les processus sur toutes les bases de données
Diego Andrés Díaz Espinoza
10

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

kill USER username;

Cela tuera tous les processus sous le nom d'utilisateur fourni. parce que la plupart des gens utilisent le même utilisateur pour tous les usages, cela fonctionne!

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

Maulik Gangani
la source
3
Dans quelle version de MySQL existe-t-il? Je ne le vois pas documenté dans la référence MySQL 5.7 ; il n'y a aucune preuve qu'il est possible de tuer par l' utilisateur: KILL [CONNECTION | QUERY] processlist_id. J'ai essayé votre requête dans MySQL 5.6.34 et c'est considéré comme une erreur de syntaxe.
Birchlabs
4
J'ai essayé ceci dans l'invite MySQL 5.6.34: mysql> 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 Votre réponse est probablement une fonctionnalité particulière à MariaDB uniquement.
Birchlabs
Cela ne fonctionne pas pour Mysql. Veuillez lire avant de publier des conseils relatifs à d'autres systèmes de base de données ...
RyanH
7

Ce qui suit va créer une procédure stockée simple qui utilise un curseur pour tuer tous les processus un par un à l'exception du processus actuellement utilisé:

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;
Steve Chambers
la source
6

J'ai récemment eu besoin de faire ça et je suis venu avec ça

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

Iberê
la source
5

TUER TOUTES LES QUESTIONS SELECT

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

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
mikesl
la source
4

Connectez-vous à Mysql en tant qu'administrateur:

 mysql -uroot -ppassword;

Et puis exécutez 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. Vous pouvez maintenant tuer la connexion en veille comme ci-dessous:

mysql> kill 52;
Query OK, 0 rows affected (0.00 sec)
Suresh Kamrushi
la source
19
Ce n'est pas la réponse à la question. Ici, vous tuez un seul processus alors que la question est de savoir comment tuer le processus à la fois.
Hristo Petev
@ badbod99 J'ai fini par chercher ici comment tuer un processus mysql et cette réponse m'a aidé donc je l'ai voté.
Bogdan
3

Cette copie 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
Fedir RYKHTIK
la source
3

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
Wiebel
la source
2

Voici une solution que vous pouvez exécuter sans vous fier au 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 base de données dont vous souhaitez supprimer les processus. Vous pouvez réécrire la procédure stockée pour filtrer sur d'autres critères si vous le souhaitez.

APPEL kill_user_processes('devdba');

Dan Spiegel
la source
2
mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}
utilisateur3721740
la source
1
Héy. Je ne sais pas si vous êtes un robot, une communauté ou un humain, mais de toute façon, ce serait formidable si vous ajoutiez des mots expliquant ce qui se passe avec cette ligne de code et comment cela résout le problème?
Félix Gagnon-Grenier
1
Ajout des -u et -p pour donner accès à l'utilisateur ... ça marche!
Lord St John
2

Nous pouvons le faire par MySQL Workbench. Exécutez simplement ceci:

kill id;

Exemple:

kill 13412

Cela l'enlèvera.

Aroon
la source
Cela semble une meilleure réponse car il n'y avait pas de langage mentionné ci-dessus.
DeshDeep Singh
0

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

shashi009
la source
0
#! /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;
Diego Andrés Díaz Espinoza
la source
0

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

Obtenez d'abord une liste de tous les processus mysql:

ps -ax | grep mysql

Ensuite, tuez chacun d'eux avec (remplacez processId par la première colonne du résultat de la commande précédente):

kill -9 processId
Nico Prat
la source
0

Ce qui suit a très bien fonctionné pour moi:

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

J'ai utilisé la commande flush tablespour tuer toutes les connexions inactives qui étaient en fait le problème de masse.

Meltzer
la source
1
ne fonctionne pas. Rincer les tables mais maintenir les coonections de sommeil actives
gtryonp
0

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()
BohanZhang
la source
-1

Si vous utilisez laravel, c'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 l'utiliser use Illuminate\Support\Facades\DB;après votre espace de noms.

Ziaur Rahman
la source
-4

La requête 1 sélectionnez concat ('KILL', id, ';') de information_schema.processlist où user = 'username' dans outfile '/tmp/a.txt';

Requête 2 source a.txt

Cela vous permettra de supprimer toutes les requêtes de show processlist par utilisateur spécifique.

Saurav Sood
la source
J'ai voté pour puis réalisé que vous venez de copier la réponse ci-dessous rofl; stackoverflow.com/a/21547386/3652863
Robert Pounder
Pour info, c'était le mien, mais peu importe.
Saurav Sood