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.

TIMEX
fonte
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);
  }
}
Michal Čihař
fonte
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")
Angelin Nadar
fonte
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.

m8t
fonte
13

Ou ... com casca ...

service mysql restart

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

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

Maulik Gangani
fonte
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;
Steve Chambers
fonte
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.

Iberê
fonte
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;
user3269995
fonte
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
mikesl
fonte
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)
Suresh Kamrushi
fonte
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
Fedir RYKHTIK
fonte
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
wiebel
fonte
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');

Dan Spiegel
fonte
2
mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}
user3721740
fonte
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.

Aroon
fonte
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)

shashi009
fonte
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
fonte
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
Nico Prat
fonte
0

O seguinte funcionou muito bem para mim:

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

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

Meltzer
fonte
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()
BohanZhang
fonte
-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.

Ziaur Rahman
fonte
-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.

Saurav Sood
fonte
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