Wie töte ich alle Prozesse in MySQL "show processlist"?

120

Weil ich dort viele Prozesse sehe und die Spalte "Zeit" große Werte für alle zeigt.

TIMEX
quelle
Sie können auch mysqld neu starten, z. B.sudo service mysqld restart
philfreo

Antworten:

108

Sie müssen sie einzeln töten, MySQL hat keinen massiven Kill-Befehl. Sie können es in jeder Sprache schreiben, zum Beispiel in PHP können Sie Folgendes verwenden:

$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ř
quelle
das ist eine gute Idee. Lass mich versuchen, das in ein Shell-Skript auf einem Cron zu konvertieren ...!
M. Faraz
4
Shellfor i in {994..1145}; do mysql -uroot -p123456 -e "kill $i" ; done
zhuguowei
mysql -u -p -e "Prozessliste anzeigen;" | grep Schlaf | awk '{print $ 1}' | während LINE lesen; mache mysql -u -p -e "töte $ LINE"; erledigt
user3770797
212

Massentötung spart Zeit. Tun Sie es in MySql selbst:

Führen Sie diese Befehle aus

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;

Referenz

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

Wenn Sie nicht in einer Datei speichern möchten, speichern Sie in einer variable

Führen Sie einfach Ihre Eingabeaufforderung aus

> 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
quelle
13
Bitte denken Sie daran, auf die Quelle zu verweisen: mysqlperformanceblog.com/2009/05/21/…
Artem Goutsoul
2
@ArtemGoutsoul, aber ich erinnere mich nicht, dass ich auf diese Seite verwiesen habe. Es ist mein eigener Trend, dies zu tun.
Angelin Nadar
@ JanusTroelsen, aber meine Antwort ist nach 3 Jahren '12
Angelin Nadar
1
@ Angelin Nadar Danke!
Silver Light
1
@ ShankarDamodaran sicher
Angelin Nadar
16

Ich habe auch gesucht, wie man den Befehl SHOW PROCESSLIST durch MySQL analysiert, und mit einem Einzeiler in einer Shell geendet:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • Die mysqladmin-Prozessliste druckt eine Tabelle mit den Thread-IDs.
  • awk analysiert aus der zweiten Spalte nur die Zahlen (Thread-IDs) und generiert MySQL KILL-Befehle.
  • und schließlich führt der letzte Aufruf von MySQL die übergebenen Befehle aus.

Sie können grep vor dem Befehl awk ausführen , um einen bestimmten Datenbanknamen zu filtern.

m8t
quelle
13

Oder ... in der Schale ...

service mysql restart

Ja, ich weiß, ich bin faul, aber es kann auch praktisch sein.

EcchiOli
quelle
10
Dies ist eine sehr schlechte Idee ... insbesondere, wenn Sie die Tabellen-Engine im Speicher eingestellt haben, weil alle Daten verloren gehen ... oder wenn Sie den Innodb-Engine-Typ verwenden, weil alle Indizes beim Neustart
wiederholt werden
8
Außerdem werden alle Prozesse in allen Datenbanken abgebrochen
Diego Andrés Díaz Espinoza
10

Einfacher geht es nicht. Führen Sie dies einfach in der MySQL-Eingabeaufforderung aus.

kill USER username;

Alle Prozesse unter dem angegebenen Benutzernamen werden abgebrochen. Da die meisten Leute denselben Benutzer für alle Zwecke verwenden, funktioniert es!

Ich habe dies auf MariaDB getestet und bin mir nicht sicher über MySQL.

Maulik Gangani
quelle
3
In welcher Version von MySQL gibt es das? Ich sehe es nicht in der MySQL 5.7-Referenz dokumentiert . Es gibt keine Beweise dafür, dass es möglich ist, durch Benutzer zu töten : KILL [CONNECTION | QUERY] processlist_id. Ich habe Ihre Abfrage in MySQL 5.6.34 ausprobiert und sie wird als Syntaxfehler angesehen.
Birchlabs
4
Ich habe dies in der Eingabeaufforderung von MySQL 5.6.34 versucht: 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 Wahrscheinlich ist Ihre Antwort nur für MariaDB spezifisch .
Birchlabs
Dies funktioniert nicht für MySQL. Bitte lesen Sie, bevor Sie Ratschläge zu anderen DB-Systemen veröffentlichen ...
RyanH
7

Im Folgenden wird eine einfache gespeicherte Prozedur erstellt, bei der alle Prozesse nacheinander mit einem Cursor beendet werden, mit Ausnahme des aktuell verwendeten Prozesses:

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 ;

Es kann mit SELECTs ausgeführt werden, um die Prozesse davor und danach wie folgt anzuzeigen:

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

Ich musste das kürzlich tun und habe mir das ausgedacht

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

Auf diese Weise müssen Sie nicht alle Abfragen mit einem einzigen Befehl in einer Datei speichern und ausführen.

Iberê
quelle
5

TÖTEN SIE ALLE AUSGEWÄHLTEN FRAGEN

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
quelle
5

Wenn Sie kein Informationsschema haben:

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

Melden Sie sich als Administrator bei MySQL an:

 mysql -uroot -ppassword;

Und dann Befehl ausführen:

mysql> show processlist;

Sie erhalten so etwas wie unten:

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

Sie sehen vollständige Details der verschiedenen Verbindungen. Jetzt können Sie die schlafende Verbindung wie folgt beenden:

mysql> kill 52;
Query OK, 0 rows affected (0.00 sec)
Suresh Kamrushi
quelle
19
Dies ist nicht die Antwort auf die Frage. Hier beenden Sie einen einzelnen Prozess, während die Frage lautet, wie Sie den Prozess sofort beenden können.
Hristo Petev
@ badbod99 Ich bin hier gelandet und habe nach einer Möglichkeit gesucht, einen MySQL-Prozess zu beenden. Diese Antwort hat mir geholfen, also habe ich sie positiv bewertet.
Bogdan
3

Dieser Ausschnitt hat bei mir (MySQL Server 5.5) funktioniert, um alle MySQL-Prozesse zu beenden:

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

Ich würde Bash und MySQL kombinieren:

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
quelle
2

Hier ist eine Lösung, die Sie ausführen können, ohne sich auf das Betriebssystem verlassen zu müssen:

SCHRITT 1: Erstellen Sie eine gespeicherte Prozedur.

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 ;

SCHRITT 2: Rufen Sie die gespeicherte Prozedur mit dem Namen eines Datenbankbenutzers auf, dessen Prozesse Sie beenden möchten. Sie können die gespeicherte Prozedur neu schreiben, um nach anderen Kriterien zu filtern, wenn Sie möchten.

ANRUF kill_user_processes('devdba');

Dan Spiegel
quelle
2
mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}
user3721740
quelle
1
Sie da. Sie sind sich nicht sicher, ob Sie ein Bot, eine Community oder ein Mensch sind, aber es wäre großartig, wenn Sie einige Wörter hinzufügen würden, die erklären, was mit dieser Codezeile los ist und wie sie das vorliegende Problem löst.
Félix Gagnon-Grenier
1
-U und -p hinzugefügt, um dem Benutzer Zugriff zu gewähren ... funktioniert gut!
Lord St John
2

Wir können es mit MySQL Workbench tun. Führen Sie einfach Folgendes aus:

kill id;

Beispiel:

kill 13412

Das wird es entfernen.

Aroon
quelle
Dies klingt nach einer besseren Antwort, da oben keine Sprache erwähnt wurde.
DeshDeep Singh
0

Eine einfache Möglichkeit wäre, den MySQL-Server neu zu starten. Öffnen Sie "services.msc" in Windows Run und wählen Sie MySQL aus der Liste aus. Klicken Sie mit der rechten Maustaste und beenden Sie den Dienst. Starten Sie dann erneut, und alle Prozesse außer dem einen (standardmäßig reservierte Verbindung) wurden abgebrochen.

shashi009
quelle
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
quelle
0

Manchmal habe ich einige Zombies MySQL-Prozesse, die nicht getötet werden können (mit MAMP Pro).

Holen Sie sich zuerst eine Liste aller MySQL-Prozesse:

ps -ax | grep mysql

Töte als nächstes jeden von ihnen mit (ersetze processId durch die erste Spalte im vorherigen Befehlsergebnis):

kill -9 processId
Nico Prat
quelle
0

Folgendes hat für mich hervorragend funktioniert:

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

Ich habe den Befehl verwendet flush tables, um alle inaktiven Verbindungen zu beenden, bei denen es sich tatsächlich um das Massenproblem handelt.

Meltzer
quelle
1
funktioniert nicht Spülen Sie die Tische, aber halten Sie die Schlafverbindungen aktiv
gtryonp
0

Für die Python-Sprache können Sie dies tun

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
quelle
-1

Wenn Sie Laravel verwenden, ist dies für Sie:

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

Natürlich sollten Sie dies use Illuminate\Support\Facades\DB;nach Ihrem Namespace verwenden.

Ziaur Rahman
quelle
-4

Abfrage 1 Wählen Sie concat ('KILL', id, ';') aus information_schema.processlist aus, wobei user = 'username' in outfile '/tmp/a.txt';

Abfrage 2 Quelle a.txt

Auf diese Weise können Sie alle Abfragen in der Show-Prozessliste nach bestimmten Benutzern beenden.

Saurav Sood
quelle
Ich stimmte zu und stellte dann fest, dass Sie gerade die Antwort unter rofl kopiert haben. stackoverflow.com/a/21547386/3652863
Robert Pounder
Zu Ihrer Information, es war meine eigene, aber was auch immer.
Saurav Sood