Come uccido tutti i processi in Mysql "show processlist"?


121

Perché vedo molti processi lì e la colonna "tempo" mostra valori elevati per tutti loro.


Puoi anche riavviare mysqld, ad esempiosudo service mysqld restart
philfreo

Risposte:


108

Devi ucciderli uno per uno, MySQL non ha alcun comando di uccisione massiccia. Puoi scriverlo in qualsiasi lingua, ad esempio in PHP puoi usare qualcosa come:

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

questa è una buona idea. Fammi provare a convertirlo in uno script di shell su un cron ...!
M. Faraz

4
Shellfor i in {994..1145}; do mysql -uroot -p123456 -e "kill $i" ; done
Zhuguowei

mysql -u -p -e "mostra elenco processi;" | grep Sleep | awk '{print $ 1}' | durante la lettura LINE; esegui mysql -u -p -e "kill $ LINE"; done
user3770797

213

L' operazione di uccisione di massa fa risparmiare tempo. Fallo in MySql stesso:

Esegui questi comandi

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;

Riferimento

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

se non si desidera archiviare in file, archiviare in un file variable

Esegui semplicemente nel tuo prompt dei comandi

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

13
Ricordati di fare riferimento alla fonte: mysqlperformanceblog.com/2009/05/21/…
Artem Goutsoul

2
@ArtemGoutsoul ma non ricordo di aver fatto riferimento a questo sito. È la mia tendenza a farlo.
Angelin Nadar

@JanusTroelsen ma la mia risposta è dopo 3 anni '12
Angelin Nadar

1
@Angelin Nadar Grazie!
Silver Light

1
@ShankarDamodaran SURE
Angelin Nadar

16

Ho anche cercato come analizzare tramite MySQL il comando SHOW PROCESSLIST e terminato con una riga in una Shell:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • mysqladmin processlist stamperà una tabella con gli id ​​dei thread;
  • awk analizzerà dalla seconda colonna solo i numeri (ID thread) e genererà i comandi MySQL KILL;
  • e infine l'ultima chiamata a mysql eseguirà i comandi passati.

È possibile eseguire grep prima del comando awk per filtrare un particolare nome di database.


13

Oppure ... in guscio ...

service mysql restart

Sì, lo so, sono pigro, ma può anche essere utile.


10
questa è una pessima idea ... in particolare se hai il motore di tabella impostato in memoria, perché tutti i dati andranno persi ... o se usi il tipo di motore innodb, perché rifarà tutti gli indici al riavvio
HellBaby

8
Inoltre uccide tutti i processi su tutti i database
Diego Andrés Díaz Espinoza

10

Non diventa più semplice di questo, basta eseguirlo nel prompt di mysql.

kill USER username;

Ucciderà tutto il processo con il nome utente fornito. poiché la maggior parte delle persone usa lo stesso utente per tutti gli scopi, funziona!

Ho provato questo su MariaDB non sono sicuro di mysql.


3
In quale versione di MySQL esiste? Non lo vedo documentato nel riferimento a MySQL 5.7 ; non ci sono prove che è possibile uccidere dall'utente: KILL [CONNECTION | QUERY] processlist_id. Ho provato la tua query in MySQL 5.6.34 ed è considerata un errore di sintassi.
Birchlabs

4
L'ho provato nel prompt di 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 Probabilmente la tua risposta è una caratteristica specifica solo di MariaDB.
Birchlabs

Questo non funziona per Mysql. Si prega di leggere prima di inviare consigli relativi ad altri sistemi DB ...
RyanH

7

Quanto segue creerà una semplice procedura memorizzata che utilizza un cursore per terminare tutti i processi uno per uno tranne quello attualmente in uso:

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 ;

Può essere eseguito con SELECTs per mostrare i processi prima e dopo come segue:

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

6

Di recente avevo bisogno di farlo e mi è venuto in mente questo

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

In questo modo, non è necessario archiviare su file ed eseguire tutte le query con un singolo comando.


5

KILL TUTTE LE DOMANDE SELEZIONATE

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

5

Se non disponi di information_schema:

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

4

accedi a Mysql come amministratore:

 mysql -uroot -ppassword;

E poi eseguire il comando:

mysql> show processlist;

Otterrai qualcosa come di seguito:

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

Vedrai i dettagli completi delle diverse connessioni. Ora puoi interrompere la connessione inattiva come di seguito:

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

19
Questa non è la risposta alla domanda. Qui stai uccidendo un singolo processo mentre la domanda è come puoi uccidere il processo contemporaneamente.
Hristo Petev

@ badbod99 Sono finito qui alla ricerca di come uccidere un processo mysql e questa risposta mi ha aiutato, quindi l'ho votato.
Bogdan

3

Questo frammento ha funzionato per me (server MySQL 5.5) per uccidere tutti i processi MySQL:

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

3

Combinerei bash e 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

2

Ecco una soluzione che puoi eseguire senza fare affidamento sul sistema operativo:

PASSAGGIO 1: creare una procedura memorizzata.

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 ;

PASSAGGIO 2: chiamare la procedura memorizzata dandogli il nome di un utente del database di cui si desidera terminare i processi. Potresti riscrivere la stored procedure per filtrare in base ad altri criteri, se lo desideri.

CHIAMATA kill_user_processes('devdba');


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

1
Ehilà. Non sei sicuro di essere un bot, una community o un essere umano, ma comunque, sarebbe fantastico se aggiungessi alcune parole per spiegare cosa sta succedendo con questa riga di codice e come risolve il problema in questione?
Félix Gagnon-Grenier

1
Aggiunti -u e -p per dare accesso all'utente ... il lavoro va bene!
Lord St John,

2

Possiamo farlo da MySQL Workbench. Basta eseguire questo:

kill id;

Esempio:

kill 13412

Questo lo rimuoverà.


Questa sembra una risposta migliore in quanto non c'era la lingua menzionata sopra.
DeshDeep Singh

0

Un modo semplice sarebbe riavviare il server mysql .. Apri "services.msc" in Windows Esegui, seleziona Mysql dall'elenco. Fare clic con il tasto destro e interrompere il servizio. Quindi ricomincia e tutti i processi sarebbero stati uccisi tranne quello (la connessione riservata predefinita)


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;

0

A volte ho alcuni processi mysql di zombi che non possono essere uccisi (usando MAMP Pro).

Per prima cosa ottieni un elenco di tutti i processi mysql:

ps -ax | grep mysql

Quindi uccidi ognuno di loro con (sostituisci processId con la prima colonna nel risultato del comando precedente):

kill -9 processId

0

Quanto segue ha funzionato alla grande per me:

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

0

Ho usato il comando flush tablesper uccidere tutte le connessioni inattive che erano effettivamente il problema di massa.


1
non funziona. Lavare i tavoli ma mantenere attive le connessioni di sonno
gtryonp

0

per il linguaggio Python, puoi fare così

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

-1

Se stai usando laravel, questo è per te:

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

Ovviamente dovresti usarlo use Illuminate\Support\Facades\DB;dopo il tuo spazio dei nomi.


-4

Query 1 select concat ('KILL', id, ';') da information_schema.processlist dove user = 'username' in outfile '/tmp/a.txt';

Fonte della query 2 a.txt

Ciò ti consentirà di terminare tutte le query in show processlist da parte di un utente specifico.


Ho votato positivamente e poi ho realizzato che hai appena copiato la risposta sotto rofl; stackoverflow.com/a/21547386/3652863
Robert Pounder,

Cordiali saluti, era mio, ma qualunque cosa.
Saurav Sood
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.