Mysqlの「show processlist」のすべてのプロセスを強制終了するにはどうすればよいですか?


120

そこには多くのプロセスがあり、「時間」列にはそれらすべての大きな値が表示されています。


たとえば、mysqldを再起動することもできますsudo service mysqld restart
philfreo

回答:


108

MySQLには1つずつ殺す必要があります。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);
  }
}

それはいいアイデアです。Lemmeはそれをcron上のシェルスクリプトに変換してみてください...!
M.ファラス

4
シェルfor i in {994..1145}; do mysql -uroot -p123456 -e "kill $i" ; done
zhuguowei 2016

mysql -u -p -e "show processlist;" | grep Sleep | awk '{print $ 1}' | LINEを読みながら; mysql -u -p -e "kill $ LINE"; 完了
user3770797 2017年

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/...
アルテムGoutsoul

2
@ArtemGoutsoulですが、このサイトを参照したことを覚えていません。これを行う私の独自の傾向。
アンジェリンナダー

@JanusTroelsenですが、私の答えは3年'12
アンジェ

1
@Angelin Nadarありがとうございます!
Silver Light

1
@ShankarDamodaran SURE
アンジェ

16

MySQLを介してコマンドSHOW PROCESSLISTを解析する方法も検索し、シェルのワンライナーで終了しました。

mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
  • mysqladmin processlistはスレッドIDを含むテーブルを出力します。
  • awkは2列目から数値(スレッドID)のみを解析し、MySQL KILLコマンドを生成します。
  • 最後に、mysqlへの最後の呼び出しで、渡されたコマンドが実行されます。

awkコマンドの前にgrepを実行して、特定のデータベース名をフィルタリングできます。


13

または...シェルで...

service mysql restart

ええ、私は知っています、私は怠惰ですが、それも便利かもしれません。


10
これは非常に悪い考えです...特に、テーブルエンジンがメモリに設定されている場合、すべてのデータが失われます...またはinnodbエンジンタイプを使用する場合、再起動時にすべてのインデックスがやり直されます
HellBaby

8
また、すべてのデータベースのすべてのプロセスを強制終了します
DiegoAndrésDíazEspinoza 2016年

10

これより簡単になることはありません。これをmysqlプロンプトで実行するだけです。

kill USER username;

指定されたユーザー名ですべてのプロセスを強制終了します。ほとんどの人がすべての目的で同じユーザーを使用しているので、うまくいきます!

mysqlについてわからないMariaDBでこれをテストしました。


3
MySQLのどのバージョンに存在しますか?MySQL 5.7リファレンスに記載されていません。ユーザーが殺すことができるという証拠はありません:KILL [CONNECTION | QUERY] processlist_id。MySQL 5.6.34でクエリを試しましたが、構文エラーと見なされます。
Birchlabs 2017

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 2017

これはMysqlでは機能しません。他のDBシステムに関連するアドバイスを投稿する前に読んでください...
RyanH

7

次は、カーソルを使用して、現在使用されているプロセスを除くすべてのプロセスを1つずつ強制終了する単純なストアドプロシージャを作成します。

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 ;

SELECT次のようにs で実行して、前後のプロセスを表示できます。

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;

そうすれば、1つのコマンドですべてのクエリを保存して実行する必要はありません。


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にadminとしてログインします。

 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 14

@ 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サーバーを再起動することです。Windowsで「services.msc」を開き、[実行]をクリックして、リストから[Mysql]を選択します。右クリックしてサービスを停止します。次に、もう一度起動すると、1つを除いてすべてのプロセスが強制終了されます(デフォルトの予約済み接続)


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

次に、それらすべてをkillします(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 information_schema.processlistからconcat( 'KILL'、id、 ';')を選択し、user = 'username'をoutfile '/tmp/a.txt'に挿入します。

クエリ2ソースa.txt

これにより、特定のユーザーによるshow processlist内のすべてのクエリを強制終了できます。


私は賛成して、あなたがroflの下に答えをコピーしたことに気づきました stackoverflow.com/a/21547386/3652863
Robert Pounder

ちなみにそれは私自身のものでしたが、何でも。
Saurav Sood 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.