Jak zabić wszystkie procesy w MySQL „pokaż listę procesów”?


121

Ponieważ widzę tam wiele procesów, a kolumna „czas” pokazuje duże wartości dla nich wszystkich.


Możesz także zrestartować mysqld, np.sudo service mysqld restart
philfreo

Odpowiedzi:


108

Musisz zabijać je jeden po drugim, MySQL nie ma żadnego ogromnego polecenia zabicia. Możesz napisać skrypt w dowolnym języku, na przykład w PHP możesz użyć czegoś takiego:

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

to dobry pomysł. Pozwólcie, że spróbuję przekonwertować to na skrypt powłoki na cronie ...!
M. Faraz,

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

mysql -u -p -e "pokaż listę procesów;" | grep Sleep | awk '{print $ 1}' | podczas czytania LINE; do mysql -u -p -e "kill $ LINE"; gotowe
user3770797

213

Operacja masowego zabijania oszczędza czas. Zrób to w samym MySql:

Uruchom te polecenia

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;

Odniesienie

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

jeśli nie chcesz przechowywać w pliku, zapisz w pliku variable

Po prostu uruchom w wierszu poleceń

> 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
Pamiętaj, aby odwołać się do źródła: mysqlperformanceblog.com/2009/05/21/…
Artem Goutsoul

2
@ArtemGoutsoul, ale nie pamiętam, że odwołałem się do tej witryny. To mój własny trend.
Angelin Nadar

@JanusTroelsen, ale moja odpowiedź jest po 3 latach '12
Angelin Nadar

1
@Angelin Nadar Dziękuję!
Silver Light

1
@ShankarDamodaran SURE
Angelin Nadar

16

Szukałem również, jak przeanalizować MySQL polecenie POKAŻ LISTĘ PROCESÓW i zakończyło się jednym wierszem w powłoce:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • mysqladmin processlist wypisze tabelę z identyfikatorami wątków;
  • awk przeanalizuje z drugiej kolumny tylko liczby (identyfikatory wątków) i wygeneruje polecenia MySQL KILL;
  • i wreszcie ostatnie wywołanie mysql wykona przekazane polecenia.

Możesz uruchomić grep przed komendą awk, aby przefiltrować określoną nazwę bazy danych.


13

Albo ... w skorupce ...

service mysql restart

Tak, wiem, jestem leniwy, ale to też może być przydatne.


10
to jest bardzo zły pomysł ... szczególnie jeśli masz silnik tabeli ustawiony na pamięci, ponieważ wszystkie dane zostaną utracone ... lub jeśli użyjesz silnika typu innodb, ponieważ spowoduje to ponowne wykonanie wszystkich indeksów przy restarcie
HellBaby

8
Również zabija cały proces we wszystkich bazach danych
Diego Andrés Díaz Espinoza

9

Tylko dla mariaDB

Nie jest to prostsze niż to, po prostu wykonaj to w zachęcie mysql.

kill USER username;

Zabije cały proces pod podaną nazwą użytkownika. ponieważ większość ludzi używa tego samego użytkownika do wszystkich celów, to działa!

Przetestowałem to na MariaDB nie jestem pewien co do mysql.


3
W której wersji MySQL to istnieje? Nie widzę tego w dokumentacji MySQL 5.7 ; Nie ma dowodów, że to możliwe, aby zabić przez użytkownika: KILL [CONNECTION | QUERY] processlist_id. Wypróbowałem twoje zapytanie w MySQL 5.6.34 i jest uważane za błąd składni.
Birchlabs,

4
Wypróbowałem to w zachęcie 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 Prawdopodobnie twoja odpowiedź dotyczy tylko funkcji MariaDB.
Birchlabs,

To nie działa w przypadku MySQL. Proszę przeczytać przed wysłaniem porad dotyczących innych systemów DB ...
RyanH

7

Poniższe spowoduje utworzenie prostej procedury składowanej, która używa kursora do zabijania wszystkich procesów jeden po drugim, z wyjątkiem aktualnie używanego procesu:

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 ;

Można go uruchomić za pomocą SELECTs, aby wyświetlić procesy przed i po w następujący sposób:

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

6

Niedawno musiałem to zrobić i wymyśliłem to

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

W ten sposób nie musisz przechowywać w pliku i uruchamiać wszystkich zapytań za pomocą jednego polecenia.


5

ZABIJ WSZYSTKIE WYBRANE PYTANIA

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

Jeśli nie masz information_schema:

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

4

zaloguj się do MySQL jako admin:

 mysql -uroot -ppassword;

A potem uruchom polecenie:

mysql> show processlist;

Otrzymasz coś takiego jak poniżej:

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

Zobaczysz pełne szczegóły różnych połączeń. Teraz możesz zabić połączenie do spania, jak poniżej:

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

19
To nie jest odpowiedź na pytanie. Tutaj zabijasz pojedynczy proces, podczas gdy pytanie brzmi, jak możesz zabić proces na raz.
Hristo Petev

@ badbod99 Skończyło się na tym, że szukałem sposobu na zabicie procesu mysql i ta odpowiedź pomogła mi, więc zagłosowałem za nią.
Bogdan

3

Ten fragment działał dla mnie (serwer MySQL 5.5), aby zabić wszystkie procesy MySQL:

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

3

Połączyłbym bash i 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

Oto rozwiązanie, które możesz wykonać bez polegania na systemie operacyjnym:

KROK 1: Utwórz procedurę składowaną.

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 ;

KROK 2: Wywołaj procedurę składowaną, podając nazwę użytkownika bazy danych, którego procesy chcesz zabić. Jeśli chcesz, możesz przepisać procedurę składowaną, aby filtrować według innych kryteriów.

POŁĄCZENIE 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
No hej. Nie jesteś pewien, czy jesteś botem, społecznością czy człowiekiem, ale tak czy inaczej, byłoby wspaniale, gdybyś dodał kilka słów wyjaśniających, co się dzieje z tą linią kodu i jak rozwiązuje on problem?
Félix Gagnon-Grenier

1
Dodano -u i -p, aby dać dostęp użytkownikowi ... wszystko w porządku!
Lord St John

2

Możemy to zrobić za pomocą MySQL Workbench. Po prostu wykonaj to:

kill id;

Przykład:

kill 13412

To go usunie.


To brzmi lepiej, ponieważ nie wspomniano powyżej języka.
DeshDeep Singh,

0

Łatwym sposobem byłoby ponowne uruchomienie serwera mysql. Otwórz "services.msc" w systemie Windows Uruchom, wybierz Mysql z listy. Kliknij prawym przyciskiem myszy i zatrzymaj usługę. Następnie Uruchom ponownie, a wszystkie procesy zostałyby zabite z wyjątkiem jednego (domyślne połączenie zarezerwowane)


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

Czasami mam procesy mysql zombie, których nie można zabić (przy użyciu MAMP Pro).

Najpierw pobierz listę wszystkich procesów mysql:

ps -ax | grep mysql

Następnie zabij każdy z nich (zamień processId na pierwszą kolumnę w wyniku poprzedniego polecenia):

kill -9 processId

0

Następujące działały dla mnie świetnie:

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

0

Użyłem polecenia, flush tablesaby zabić wszystkie nieaktywne połączenia, które są w rzeczywistości problemem masy.


1
nie działa.
Opróżnij

0

w przypadku języka python można to zrobić w ten sposób

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

Jeśli używasz laravel, to jest to dla Ciebie:

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

Oczywiście powinieneś użyć tego use Illuminate\Support\Facades\DB;po swojej przestrzeni nazw.


-4

Zapytanie 1 wybierz concat ('KILL', id, ';') z information_schema.processlist gdzie user = 'username' do outfile '/tmp/a.txt';

Zapytanie 2 źródło a.txt

Umożliwi to zabicie wszystkich zapytań w show processlist przez określonego użytkownika.


Głosowałem za, a potem zdałem sobie sprawę, że właśnie skopiowałeś odpowiedź poniżej rofl; stackoverflow.com/a/21547386/3652863
Robert Pounder

FYI to było moje, ale nieważne.
Saurav Sood
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.