¿Cómo elimino todos los procesos en Mysql "show processlist"?


121

Porque veo muchos procesos allí, y la columna "tiempo" muestra grandes valores para todos ellos.


También puede reiniciar mysqld, por ejemplo,sudo service mysqld restart
philfreo

Respuestas:


108

Necesita matarlos uno por uno, MySQL no tiene ningún comando de matar masivo. Puede escribirlo en cualquier idioma, por ejemplo, en PHP puede usar algo como:

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

eso es una buena idea. ¡Déjame intentar convertir eso en un script de shell en un cron ...!
M. Faraz

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

mysql -u -p -e "mostrar lista de procesos;" | grep Sleep | awk '{imprimir $ 1}' | mientras lee LINE; hacer mysql -u -p -e "matar $ LINE"; hecho
user3770797

213

La operación de matanza masiva ahorra tiempo. Hágalo en MySql mismo:

Ejecuta estos comandos

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;

Referencia

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

si no desea almacenar en un archivo, guárdelo en un variable

Simplemente ejecute en su símbolo del sistema

> 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
Recuerde consultar la fuente: mysqlperformanceblog.com/2009/05/21/…
Artem Goutsoul

2
@ArtemGoutsoul pero no recuerdo haber hecho referencia a este sitio. Es mi propia tendencia de hacer esto.
Angelin Nadar

@JanusTroelsen pero mi respuesta es después de 3 años '12
Angelin Nadar

1
@Angelin Nadar ¡Gracias!
Silver Light

1
@ShankarDamodaran SURE
Angelin Nadar

16

También he buscado cómo analizar a través de MySQL el comando SHOW PROCESSLIST y terminé con una línea en un Shell:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • mysqladmin processlist imprimirá una tabla con los identificadores del hilo;
  • awk analizará desde la segunda columna solo los números (ID de hilo) y generará comandos KILL de MySQL;
  • y finalmente la última llamada a mysql ejecutará los comandos pasados.

Puede ejecutar grep antes del comando awk para filtrar un nombre de base de datos en particular.


13

O ... con cáscara ...

service mysql restart

Sí, lo sé, soy vago, pero también puede ser útil.


10
esta es una muy mala idea ... en especial si tiene el motor de tabla configurado en la memoria, porque todos los datos se perderán ... o si usa el tipo de motor innodb, porque
rehacerá

8
También mata todo el proceso en todas las bases de datos
Diego Andrés Díaz Espinoza

10

No se vuelve más simple que esto, simplemente ejecute esto en el indicador de mysql.

kill USER username;

Matará todo el proceso bajo el nombre de usuario proporcionado. porque la mayoría de la gente usa el mismo usuario para todos los propósitos, ¡funciona!

He probado esto en MariaDB, no estoy seguro de mysql.


3
¿En qué versión de MySQL existe esto? No lo veo documentado en la referencia de MySQL 5.7 ; no hay evidencia de que es posible matar por el usuario: KILL [CONNECTION | QUERY] processlist_id. Probé su consulta en MySQL 5.6.34 y se considera un error de sintaxis.
Birchlabs

4
He intentado esto en el indicador de 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 probablemente su respuesta sea una característica particular de MariaDB solamente.
Birchlabs

Esto no funciona para Mysql. Lea antes de publicar consejos relacionados con otros sistemas de base de datos ...
RyanH

7

A continuación, se creará un procedimiento almacenado simple que utiliza un cursor para matar todos los procesos uno por uno, excepto el proceso que se está utilizando actualmente:

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 ;

Se puede ejecutar con SELECTs para mostrar los procesos antes y después de la siguiente manera:

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

6

Recientemente necesitaba hacer esto y se me ocurrió esto

-- 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 esa forma, no es necesario almacenar para archivar y ejecutar todas las consultas con un solo comando.


5

MATAR TODAS LAS CONSULTAS SELECCIONADAS

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

Si no tiene information_schema:

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

4

iniciar sesión en Mysql como administrador:

 mysql -uroot -ppassword;

Y luego ejecutar el comando:

mysql> show processlist;

Obtendrá algo como a continuación:

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

Verá detalles completos de diferentes conexiones. Ahora puede eliminar la conexión para dormir como se muestra a continuación:

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

19
Ésta no es la respuesta a la pregunta. Aquí está matando un solo proceso, mientras que la pregunta es cómo puede matar el proceso a la vez.
Hristo Petev

@ badbod99 Terminé aquí buscando cómo eliminar un proceso mysql y esta respuesta me ayudó, así que voté a favor.
Bogdan

3

Este recorte funcionó para mí (servidor MySQL 5.5) para matar todos los procesos de MySQL:

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

3

Combinaría bash y 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

Aquí hay una solución que puede ejecutar sin depender del sistema operativo:

PASO 1: Cree un procedimiento almacenado.

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 ;

PASO 2: Llame al procedimiento almacenado dándole el nombre de un usuario de la base de datos cuyos procesos desea eliminar. Puede reescribir el procedimiento almacenado para filtrar otros criterios si lo desea.

LLAMADA 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
Hola. No estoy seguro de si eres un bot, una comunidad o un ser humano, pero de todos modos, sería genial si agregaras algunas palabras que expliquen lo que está sucediendo con esta línea de código y cómo resuelve el problema en cuestión.
Félix Gagnon-Grenier

1
Se agregaron -u y -p para dar acceso al usuario ... ¡el trabajo está bien!
Lord St John

2

Podemos hacerlo mediante MySQL Workbench. Simplemente ejecute esto:

kill id;

Ejemplo:

kill 13412

Eso lo eliminará.


Esto suena mejor respuesta ya que no se mencionó el lenguaje anteriormente.
DeshDeep Singh

0

Una forma fácil sería reiniciar el servidor mysql. Abra "services.msc" en Windows Ejecutar, seleccione Mysql de la lista. Haga clic derecho y detenga el servicio. Luego, comience de nuevo y todos los procesos habrían sido eliminados excepto uno (la conexión reservada predeterminada)


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 veces tengo algunos procesos zombies mysql que no se pueden matar (usando MAMP Pro).

Primero obtenga una lista de todos los procesos de mysql:

ps -ax | grep mysql

Luego elimine a cada uno de ellos con (reemplace processId con la primera columna en el resultado del comando anterior):

kill -9 processId

0

Lo siguiente funcionó muy bien para mí:

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

0

Usé el comando flush tablespara eliminar todas las conexiones inactivas que eran en realidad el problema masivo.


1
no funciona. Vacíe las mesas pero mantenga las coonecciones del sueño activas
gtryonp

0

para el lenguaje Python, puedes hacer esto

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

Si está utilizando laravel, esto es para usted:

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

Por supuesto, debe usar esto use Illuminate\Support\Facades\DB;después de su espacio de nombres.


-4

Consulta 1 seleccione concat ('KILL', id, ';') de information_schema.processlist donde usuario = 'nombre de usuario' en el archivo de salida '/tmp/a.txt';

Fuente de la consulta 2 a.txt

Esto le permitirá eliminar todas las consultas en mostrar lista de procesos por usuario específico.


Yo voté a favor y luego me di cuenta de que simplemente copiaste la respuesta debajo de rofl; stackoverflow.com/a/21547386/3652863
Robert Pounder

Para tu información, era mío, pero lo que sea.
Saurav Sood
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.