Mysql "show processlist" içindeki tüm süreçleri nasıl öldürebilirim?


121

Çünkü orada çok fazla işlem görüyorum ve "zaman" sütunu hepsi için büyük değerler gösteriyor.


Ayrıca sudo service mysqld restart
mysqld'yi

Yanıtlar:


108

Onları birer birer öldürmeniz gerekiyor, MySQL'in büyük bir öldürme komutu yok. Herhangi bir dilde komut dosyası yazabilirsiniz, örneğin PHP'de aşağıdaki gibi bir şey kullanabilirsiniz:

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

bu iyi bir fikir. Lemme bunu bir cron'da bir kabuk betiğine dönüştürmeyi dene ...!
M.Faraz

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

mysql -u -p -e "işlem listesini göster;" | grep Uyku | awk '{print $ 1}' | HAT okurken; do mysql -u -p -e "$ HATTI öldür"; done
user3770797

213

Toplu öldürme operasyonu zaman kazandırır. MySql'in kendisinde yapın:

Bu komutları çalıştırın

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;

Referans

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

dosyada saklamak istemiyorsanız, bir variable

Sadece komut isteminizde çalıştırın

> 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
Lütfen kaynağa başvurmayı unutmayın: mysqlperformanceblog.com/2009/05/21/…
Artem Goutsoul

2
@ArtemGoutsoul ama bu siteye başvurduğumu hatırlamıyorum. Bunu yapmak benim kendi eğilimim.
Angelin Nadar

@JanusTroelsen ama cevabım 3 yrs '12 sonra
Angelin Nadar

1
@Angelin Nadar Teşekkürler!
Silver Light

1
@ShankarDamodaran EMİN
Angelin Nadar

16

Ayrıca MySQL ile SHOW PROCESSLIST komutunun nasıl ayrıştırılacağını araştırdım ve bir Kabukta tek satırlık bir sonuçla bitirdim:

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • mysqladmin processlist iş parçacığı kimlikleri ile bir tablo basacaktır;
  • awk , ikinci sütundan yalnızca sayıları (evre kimlikleri) ayrıştıracak ve MySQL KILL komutlarını oluşturacaktır;
  • ve son olarak son çağrı mysql geçti komutları çalıştırır.

Belirli bir veritabanı adını filtrelemek için awk komutundan önce grep çalıştırabilirsiniz .


13

Veya ... kabukta ...

service mysql restart

Evet, biliyorum, tembelim ama kullanışlı da olabilir.


10
bu çok kötü bir fikir ... özellikle belleğe ayarlanmış tablo motorunuz varsa, tüm verilerin kaybolmasına neden olur ... veya innodb motor türünü kullanırsanız, çünkü yeniden başlatıldığında tüm dizinleri yeniden
yapacaktır

8
Ayrıca tüm veri tabanlarındaki tüm süreçleri öldürür
Diego Andrés Díaz Espinoza

9

Bundan daha basit olmaz, sadece bunu mysql komut isteminde çalıştırın.

kill USER username;

Sağlanan kullanıcı adı altındaki tüm işlemleri öldürecektir. çünkü çoğu insan tüm amaç için aynı kullanıcıyı kullanıyor, işe yarıyor!

Bunu MariaDB'de test ettim, mysql hakkında emin değilim.


3
Bu MySQL'in hangi sürümünde mevcut? MySQL 5.7 referansında belgelendiğini görmüyorum ; kullanıcı tarafından öldürmek mümkün olduğunu kanıt yok: KILL [CONNECTION | QUERY] processlist_id. Sorgunuzu MySQL 5.6.34'te denedim ve bir sözdizimi hatası olarak kabul edildi.
Birchlabs

4
Bunu MySQL 5.6.34 isteminde denedim: 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 Muhtemelen cevabınız yalnızca MariaDB'ye özgü bir özelliktir.
Birchlabs

Bu Mysql için çalışmıyor. Lütfen diğer DB sistemleriyle ilgili tavsiye göndermeden önce okuyun ...
RyanH

7

Aşağıdakiler, şu anda kullanılmakta olan işlem haricinde tüm işlemleri tek tek öldürmek için bir imleç kullanan basit bir saklı yordam oluşturacaktır:

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 ;

Önceki SELECTve sonraki süreçleri aşağıdaki gibi göstermek için s ile çalıştırılabilir :

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

6

Son zamanlarda bunu yapmam gerekiyordu ve bunu buldum

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

Bu şekilde, tüm sorguları tek bir komutla dosyalamak ve çalıştırmak için depolamanıza gerek kalmaz.


5

TÜM SEÇİLEN SORGULARI ÖLDÜR

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 yoksa:

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

4

Mysql'de yönetici olarak oturum açın:

 mysql -uroot -ppassword;

Ve komut çalıştırdıktan sonra:

mysql> show processlist;

Aşağıdaki gibi bir şey alacaksınız:

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

Farklı bağlantıların tüm ayrıntılarını göreceksiniz. Şimdi uyku bağlantısını aşağıdaki gibi kapatabilirsiniz:

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

19
Bu sorunun cevabı değil. Burada tek bir süreci öldürüyorsunuz, soru ise süreci bir seferde nasıl sonlandırabilirsiniz.
Hristo Petev

@ badbod99 Burada bir mysql sürecini nasıl öldüreceğimi aradım ve bu cevap bana yardımcı oldu, ben de ona oy verdim.
Bogdan

3

Bu, tüm MySQL işlemlerini öldürmek için benim için çalıştı (MySQL sunucusu 5.5):

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

3

Bash ve mysql'i birleştirirdim:

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

İşte işletim sistemine güvenmeden uygulayabileceğiniz bir çözüm:

ADIM 1: Bir saklı yordam oluşturun.

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 ;

ADIM 2: İşlemlerini sonlandırmak istediğiniz bir veritabanı kullanıcısının adını vererek saklı yordamı çağırın. İsterseniz başka ölçütlere göre filtrelemek için saklı yordamı yeniden yazabilirsiniz.

ARAMAK 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
Selam. Bot mu, Topluluk mu yoksa insan mı emin değilim ama yine de, bu kod satırında neler olup bittiğini ve eldeki sorunu nasıl çözdüğünü açıklayan bazı kelimeler eklerseniz harika olur mu?
Félix Gagnon-Grenier

1
Kullanıcıya erişim sağlamak için -u ve -p eklendi ... iş sorun değil!
Lord St John

2

MySQL Workbench ile yapabiliriz. Sadece şunu çalıştırın:

kill id;

Misal:

kill 13412

Bu onu kaldıracak.


Yukarıda bahsedilen dil olmadığı için bu daha iyi bir cevap gibi görünüyor.
DeshDeep Singh

0

Kolay bir yol mysql sunucusunu yeniden başlatmak olabilir .. Windows Çalıştır'da "services.msc" dosyasını açın, listeden Mysql'i seçin. Sağ tıklayın ve hizmeti durdurun. Sonra tekrar başlayın ve bir (varsayılan ayrılmış bağlantı) hariç tüm işlemler öldürülürdü.


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

Bazen öldürülemeyen bazı zombilerim var mysql süreçleri (MAMP Pro kullanarak).

Önce tüm mysql işlemlerinin bir listesini alın:

ps -ax | grep mysql

Sonra her birini öldür (processId'yi önceki komut sonucundaki ilk sütunla değiştirin):

kill -9 processId

0

Aşağıdakiler benim için harika çalıştı:

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

0

Komutu flush tables, aslında toplu problemin olduğu tüm aktif olmayan bağlantıları öldürmek için kullandım .


1
çalışmıyor. Tabloları
temizleyin

0

python dili için bunu yapabilirsin

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 kullanıyorsanız, o zaman bu tam size göre:

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

Elbette bunu use Illuminate\Support\Facades\DB;ad alanınızdan sonra kullanmalısınız .


-4

Sorgu 1 information_schema.processlist'ten concat ('KILL', id, ';') seçin; burada user = 'username' outfile '/tmp/a.txt';

Sorgu 2 kaynağı a.txt

Bu, gösteri işlem listesindeki tüm sorguları belirli bir kullanıcıya göre sonlandırmanızı sağlayacaktır.


Oy verdim, sonra rofl'nin altındaki cevabı kopyaladığınızı fark ettim; stackoverflow.com/a/21547386/3652863
Robert Pounder

Bilginize, kendime aitti ama her neyse.
Saurav Sood
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.