Как мне убить все процессы в Mysql «show processlist»?


121

Потому что я вижу там много процессов, и столбец «время» показывает большие значения для всех из них.


Вы также можете перезапустить mysqld, например,sudo service mysqld restart
philfreo 04

Ответы:


108

Вам нужно убить их одного за другим, MySQL не имеет никакой массивной команды kill. Вы можете написать сценарий на любом языке, например, в PHP вы можете использовать что-то вроде:

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

что это хорошая идея. Дайте мне попробовать преобразовать это в сценарий оболочки на cron ...!
M. Faraz

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

mysql -u -p -e "показать список процессов;" | grep Sleep | awk '{print $ 1}' | пока читал LINE; сделать mysql -u -p -e "kill $ LINE"; done
user3770797 04

213

Операция массового убийства экономит время. Сделайте это в самом MySql:

Выполните эти команды

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;

Ссылка

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

если вы не хотите хранить в файле, сохраните в variable

Просто запустите в командной строке

> 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
Пожалуйста, не забудьте сослаться на источник: mysqlperformanceblog.com/2009/05/21/…
Артем Гутсул

2
@ArtemGoutsoul, но я не помню, что ссылался на этот сайт. Это моя собственная тенденция.
Angelin Nadar

@JanusTroelsen, но мой ответ - после 3 лет '12
Ангелин Надар

1
@Angelin Nadar Спасибо!
Silver Light

1
@ShankarDamodaran SURE
Angelin Nadar

16

Я также искал, как разобрать через MySQL команду SHOW PROCESSLIST и закончил однострочным текстом в оболочке:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • mysqladmin processlist напечатает таблицу с идентификаторами потоков;
  • awk будет анализировать из второго столбца только числа (идентификаторы потоков) и генерировать команды MySQL KILL;
  • и, наконец, последний вызов mysql выполнит переданные команды.

Вы можете запустить grep перед командой awk, чтобы отфильтровать конкретное имя базы данных.


13

Или ... в оболочке ...

service mysql restart

Да, я знаю, я ленив, но это тоже может пригодиться.


10
это очень плохая идея ... особенно, если у вас установлен движок таблиц в памяти, потому что все данные будут потеряны ... или если вы используете тип движка innodb, потому что он повторит все индексы при перезапуске
HellBaby

8
Также он убивает весь процесс во всех базах данных
Диего Андрес Диас Эспиноза

9

Только для mariaDB

Это не становится проще, просто выполните это в командной строке mysql.

kill USER username;

Это убьет весь процесс под указанным именем пользователя. потому что большинство людей используют одного и того же пользователя для всех целей, это работает!

Я тестировал это на MariaDB, не уверен в mysql.


3
В какой версии MySQL это существует? Я не вижу это задокументировано в справочнике MySQL 5.7 ; нет никаких доказательств того, что можно убить пользователем: KILL [CONNECTION | QUERY] processlist_id. Я попробовал ваш запрос в MySQL 5.6.34, и это было признано синтаксической ошибкой.
Birchlabs

4
Я пробовал это в приглашении 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 возможно, ваш ответ относится только к MariaDB.
Birchlabs

Это не работает для Mysql. Пожалуйста, прочтите, прежде чем публиковать советы, касающиеся других систем БД ...
RyanH

7

Следующее создаст простую хранимую процедуру, которая использует курсор для уничтожения всех процессов один за другим, кроме процесса, который используется в данный момент:

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 ;

Его можно запустить с SELECTs, чтобы показать процессы до и после следующего:

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

6

Мне недавно нужно было это сделать, и я придумал это

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

Таким образом, вам не нужно сохранять в файл и выполнять все запросы с помощью одной команды.


5

УБИТЬ ВСЕ ВЫБОРНЫЕ ЗАПРОСЫ

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

Если у вас нет information_schema:

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

4

войдите в Mysql как администратор:

 mysql -uroot -ppassword;

И затем запустите команду:

mysql> show processlist;

Вы получите примерно следующее:

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

Вы увидите полную информацию о различных подключениях. Теперь вы можете отключить спящее соединение, как показано ниже:

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

19
Это не ответ на вопрос. Здесь вы убиваете один процесс, а вопрос в том, как вы можете убить процесс сразу.
Hristo Petev

@ badbod99 Я оказался здесь в поисках того, как убить процесс mysql, и этот ответ помог мне, поэтому я проголосовал за него.
Богдан

3

Этот фрагмент сработал для меня (сервер MySQL 5.5), чтобы убить все процессы MySQL:

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

3

Я бы объединил bash и 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

Вот решение, которое вы можете выполнить, не полагаясь на операционную систему:

ШАГ 1. Создайте хранимую процедуру.

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 ;

ШАГ 2: Вызовите хранимую процедуру, присвоив ей имя пользователя базы данных, чьи процессы вы хотите убить. Вы можете переписать хранимую процедуру для фильтрации по другим критериям, если хотите.

ВЫЗОВ 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
Привет всем. Не уверен, что вы бот, сообщество или человек, но в любом случае было бы здорово, если бы вы добавили несколько слов, объясняющих, что происходит с этой строкой кода и как она решает проблему?
Феликс Ганьон-Гренье

1
Добавлены -u и -p для предоставления доступа пользователю ... все в порядке!
Лорд Сент-Джон

2

Мы можем сделать это с помощью MySQL Workbench. Просто выполните это:

kill id;

Пример:

kill 13412

Это удалит его.


Это звучит лучше, поскольку выше не было языка.
DeshDeep Singh

0

Самый простой способ - перезапустить сервер mysql. Откройте "services.msc" в Windows Выполнить, выберите Mysql из списка. Щелкните правой кнопкой мыши и остановите службу. Затем запустите снова, и все процессы будут уничтожены, кроме одного (зарезервированное соединение по умолчанию)


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

Иногда у меня есть несколько зомби-процессов mysql, которые невозможно убить (с помощью MAMP Pro).

Сначала получите список всех процессов mysql:

ps -ax | grep mysql

Затем убейте каждого из них (замените processId первым столбцом в результате предыдущей команды):

kill -9 processId

0

Для меня отлично сработало следующее:

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

0

Я использовал команду, flush tablesчтобы убить все неактивные соединения, которые на самом деле были основной проблемой.


1
не работает. Промойте столы, но поддерживайте коонекции сна активными
gtryonp

0

для языка Python вы можете сделать это так

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

Если вы используете laravel, то это для вас:

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

Конечно, вы должны использовать это use Illuminate\Support\Facades\DB;после вашего пространства имен.


-4

Запрос 1 выберите concat ('KILL', id, ';') из information_schema.processlist, где user = 'username', в outfile '/tmp/a.txt';

Источник запроса 2 a.txt

Это позволит вам уничтожить все запросы в show processlist от конкретного пользователя.


Я поддержал, а затем понял, что вы просто скопировали ответ ниже rofl; stackoverflow.com/a/21547386/3652863
Роберт Паундер

К вашему сведению, это было мое собственное, но неважно.
Saurav Sood
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.