Como eu mato todos os processos no Mysql "show processlist"?


120

Porque eu vejo muitos processos lá, e a coluna "time" mostra grandes valores para todos eles.


Você também pode reiniciar o mysqld, por exemplo,sudo service mysqld restart
philfreo 4/11

Respostas:


108

Você precisa matá-los um por um, o MySQL não possui nenhum comando massivo de matança. Você pode criar um script em qualquer idioma; por exemplo, no PHP, você pode 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);
  }
}

Isso é uma boa ideia. Deixe-me tentar converter isso em um script de shell em um cron ...!
M. Faraz

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

mysql -u -p -e "show processlist;" | grep sono | awk '{print $ 1}' | enquanto lê LINE; do mysql -u -p -e "mata $ LINE"; done
user3770797

213

A operação de matar em massa economiza tempo. Faça no MySql:

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

Referência

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

Se você não deseja armazenar em um arquivo, armazene variable

Basta executar no seu prompt de comando

> 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
Lembre-se de consultar a fonte: mysqlperformanceblog.com/2009/05/21/…
Artem Goutsoul

2
@ArtemGoutsoul, mas não me lembro de me referir a este site. É minha própria tendência de fazer isso.
Angelin Nadar

@JanusTroelsen mas a minha resposta é depois de 3 anos '12
Angelin Nadar

1
@Angelin Nadar Obrigado!
Silver Light

1
@ShankarDamodaran SURE
Angelin Nadar

16

Eu também procurei como analisar através do MySQL o comando SHOW PROCESSLIST e terminei com uma linha em um shell:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • O mysqladmin processlist imprimirá uma tabela com os IDs dos threads;
  • O awk analisará a partir da segunda coluna apenas os números (IDs de thread) e gerará comandos MySQL KILL;
  • e finalmente a última chamada ao mysql executará os comandos passados.

Você pode executar grep antes do comando awk para filtrar um nome de banco de dados específico.


13

Ou ... com casca ...

service mysql restart

Sim, eu sei, sou preguiçoso, mas também pode ser útil.


10
essa é uma péssima idéia ... em especial se você tiver o mecanismo de tabela configurado na memória, pois todos os dados serão perdidos ... ou se você usar o tipo de mecanismo innodb, pois ele refará todos os índices na reinicialização
HellBaby

8
Também ele mata todos os processos em todos os bancos de dados
Diego Andrés Díaz Espinoza

10

Não fica mais simples do que isso, basta executar isso no prompt do mysql.

kill USER username;

Ele matará todo o processo sob o nome de usuário fornecido. porque a maioria das pessoas usa o mesmo usuário para todos os fins, funciona!

Eu testei isso no MariaDB não tenho certeza sobre o mysql.


3
Em qual versão do MySQL isso existe? Não o vejo documentado na referência do MySQL 5.7 ; não há nenhuma evidência de que é possível matar pelo usuário: KILL [CONNECTION | QUERY] processlist_id. Eu tentei sua consulta no MySQL 5.6.34 e é considerado um erro de sintaxe.
22417 Birchlabs

4
Eu tentei isso no prompt do 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 Provavelmente sua resposta é um recurso específico apenas para o MariaDB.
Birchlabs

Isso não funciona para o Mysql. Por favor, leia antes de aconselhamento postagem relacionadas com outros sistemas de banco de dados ...
RyanH

7

A seguir, será criado um procedimento armazenado simples que usa um cursor para eliminar todos os processos, um por um, exceto o processo atualmente sendo usado:

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 ;

Pode ser executado com SELECTs para mostrar os processos antes e depois da seguinte maneira:

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

6

Recentemente, eu precisava fazer isso e eu vim com isso

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

Dessa forma, você não precisa armazenar no arquivo e executar todas as consultas com um único comando.


5

MATAR TODAS AS CONSULTAS SELECIONADAS

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 você não possui information_schema:

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

4

faça o login no Mysql como administrador:

 mysql -uroot -ppassword;

E então execute o comando:

mysql> show processlist;

Você receberá algo como abaixo:

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

Você verá detalhes completos de diferentes conexões. Agora você pode matar a conexão adormecida como abaixo:

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

19
Esta não é a resposta para a pergunta. Aqui você está matando um único processo, enquanto a questão é como você pode matar o processo de uma só vez.
Hristo Petev

@ badbod99 Eu acabei aqui procurando como matar um processo mysql e esta resposta me ajudou, então eu votei nele.
Bogdan

3

Este snippet funcionou para mim (servidor MySQL 5.5) para matar todos os processos do MySQL:

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

3

Eu combinaria 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

Aqui está uma solução que você pode executar sem depender do sistema operacional:

PASSO 1: Crie um procedimento armazenado.

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 ;

ETAPA 2: Chame o procedimento armazenado, fornecendo o nome de um usuário do banco de dados cujos processos você deseja eliminar. Você pode reescrever o procedimento armazenado para filtrar em alguns outros critérios, se desejar.

LIGAR 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
Olá. Não tenho certeza se você é um bot, uma comunidade ou um ser humano, mas de qualquer maneira, seria ótimo se você adicionasse algumas palavras explicando o que está acontecendo com essa linha de código e como isso resolve o problema em questão?
Félix Gagnon-Grenier

1
Adicionados -u e -p para dar acesso ao usuário ... funciona bem!
Lord St John

2

Podemos fazer isso pelo MySQL Workbench. Apenas execute isto:

kill id;

Exemplo:

kill 13412

Isso irá removê-lo.


Parece uma resposta melhor, pois não havia o idioma mencionado acima.
DeshDeep Singh

0

Uma maneira fácil seria reiniciar o servidor mysql. Abra "services.msc" no Windows Run, selecione Mysql na lista. Clique com o botão direito e pare o serviço. Em seguida, inicie novamente e todos os processos teriam sido eliminados, exceto aquele (a conexão reservada padrão)


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

Às vezes, tenho alguns processos mysql de zumbis que não podem ser mortos (usando o MAMP Pro).

Primeiro obtenha uma lista de todos os processos mysql:

ps -ax | grep mysql

Em seguida, mate todos eles com (substitua processId pela primeira coluna no resultado do comando anterior):

kill -9 processId

0

O seguinte funcionou muito bem para mim:

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

0

Eu usei o comando flush tablespara matar todas as conexões inativas que, na verdade, eram o problema de massa.


1
não funciona. Lave as tabelas, mas manter a coonections sono ativo
gtryonp

0

para linguagem python, você pode fazer assim

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 você estiver usando laravel, então é para você:

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

Obviamente, você deve usar isso use Illuminate\Support\Facades\DB;após o seu espaço para nome.


-4

Consulta 1, selecione concat ('KILL', id, ';') em information_schema.processlist em que user = 'nome de usuário' entra no arquivo de saída '/tmp/a.txt';

Origem da consulta 2 a.txt

Isso permitirá que você elimine todas as consultas no show processlist por usuário específico.


Eu votei, em seguida, percebi que você acabou de copiar a resposta abaixo rofl; stackoverflow.com/a/21547386/3652863
Robert Pounder

Para sua informação, era por minha conta, mas tanto faz.
Saurav Sood
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.