itstnd@yandex.ru

Консультации

Разработка и поддержка сайтов

Как убить все зависшие процессы mysql

 mysql    

Иногда возникает необходимость убить все  зависшие процессы / запросы mysql, когда сервер перегружен, останавливать и/или перезагружать нельзя, но нужно его раздуплить срочно

1. Самый простой и безопасный способ — убить все зависшие процессы кроме своего

Подключитесь к MySQL:

mysql -u root -з

Выполните скрипт, который автоматически убьёт все соединения, кроме текущего:

SELECT CONCAT('KILL ', id, ';') 
FROM information_schema.processlist 
WHERE user != 'system user'  -- не трогаем системные
  AND id != CONNECTION_ID()  -- не трогаем своё соединение
  AND command != 'Sleep'     -- опционально: не трогаем спящие соединения
INTO OUTFILE '/tmp/kill_commands.sql';

SOURCE /tmp/kill_commands.sql;

Или в одну команду (без записи в файл):

SET @kill_sql = (
    SELECT GROUP_CONCAT(
        CONCAT('KILL ', id, ';') SEPARATOR ' '
    )
    FROM information_schema.processlist
    WHERE user != 'system user'
      AND id != CONNECTION_ID()
);

PREPARE stmt FROM @kill_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

2. Убить абсолютно все пользовательские соединения (кроме системных)

SELECT GROUP_CONCAT(CONCAT('KILL ', id, ';') SEPARATOR '\n')
FROM information_schema.processlist
WHERE user NOT IN ('system user', 'event_scheduler')
  AND id != CONNECTION_ID();

Скопируйте вывод и выполните его.

3. Быстрый способ из командной строки (без входа в MySQL)

Сначала посмотрите все процессы:

mysqladmin -u root -p processlist

Затем убейте все (кроме своего) одной командой:

mysql -u root -p -NB -e "SELECT id FROM information_schema.processlist WHERE id != CONNECTION_ID() AND user != 'system user'" | while read id; do mysql -u root -p -e "KILL $id"; done

(Введите пароль один раз при первом запросе.)

4. Перезапуск MySQL — радикальный способ (убьёт всё мгновенно)

sudo systemctl restart mysql

Все соединения разорвутся, все текущие запросы прервутся. Используйте только если другие способы не помогают или нужно срочно.

5. Если нужно регулярно чистить «зависшие» запросы

Можно настроить автоматическую очистку запросов, которые висят слишком долго:

В конфиге /etc/mysql/my.cnf добавьте:

[mysqld]
wait_timeout = 60          # разрывать неактивные соединения через 60 сек
interactive_timeout = 60
max_execution_time = 300   # прерывать запросы дольше 5 минут (MySQL 5.7+)

Перезапустите: sudo systemctl restart mysql

Рекомендация

  • Сначала всегда смотрите, что именно выполняется: SHOW FULL PROCESSLIST;
  • Убивайте только подозрительные или зависшие запросы по одному (KILL 123;)
  • Массовое убийство используйте только в экстренных случаях (например, при DDoS или зависании сервера).