mita2 database life

主にMySQLに関するメモです

ProxySQL を使った接続で KILL するのはややこしい

MySQL の KILL コマンドのおさらい

MySQL の KILL コマンドには 2種類あります。

  • KILL <CONNECTION_ID> または KILL CONNECTION <CONNECTION_ID>

    • ターゲットの接続で実行中のクエリがあれば終了し、接続も切断します。
  • KILL QUERY <CONNECTION_ID>

    • ターゲットの接続で実行中のクエリを終了します。接続は維持します。

ProxySQL経由でのKILL - IDが食い違う問題

ProxySQL を経由した状態で KILL CONNECTION をやってみます。 ID 535SELECT SLEEP(100), user FROM mysql.user を KILL しましたが、クエリは実行されたままです。

mysql> SHOW PROCESSLIST;
+-----+-----------------+<snip>+-----------------------------------------+
| Id  | User            |<snip>| Info                                    |
+-----+-----------------+<snip>+-----------------------------------------+
|   6 | system user     |<snip>| NULL                                    |
|   7 | event_scheduler |<snip>| NULL                                    |
|  10 | system user     |<snip>| NULL                                    |
|  11 | system user     |<snip>| NULL                                    |
|  12 | system user     |<snip>| NULL                                    |
|  13 | system user     |<snip>| NULL                                    |
| 517 | root            |<snip>| NULL                                    |
| 526 | root            |<snip>| SHOW PROCESSLIST                        |
| 535 | root            |<snip>| SELECT SLEEP(100), user FROM mysql.user |
+-----+-----------------+<snip>+-----------------------------------------+
9 rows in set, 1 warning (0.00 sec)

mysql> KILL CONNECTION 535;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW PROCESSLIST;
+-----+-----------------+<snip>+-----------------------------------------+
| Id  | User            |<snip>| Info                                    |
+-----+-----------------+<snip>+-----------------------------------------+
|   6 | system user     |<snip>| NULL                                    |
|   7 | event_scheduler |<snip>| NULL                                    |
|  10 | system user     |<snip>| NULL                                    |
|  11 | system user     |<snip>| NULL                                    |
|  12 | system user     |<snip>| NULL                                    |
|  13 | system user     |<snip>| NULL                                    |
| 517 | root            |<snip>| NULL                                    |
| 526 | root            |<snip>| SHOW PROCESSLIST                        |
| 535 | root            |<snip>| SELECT SLEEP(100), user FROM mysql.user |
+-----+-----------------+<snip>+-----------------------------------------+
9 rows in set, 1 warning (0.00 sec)

前回のエントリーで、ProxySQL には独自の Connection ID があることを説明しました。 ProxySQL経由の接続を ProxySQL経由の接続を使って KILLするには、ProxySQLが管理している独自のConnection IDを使う必要があります。

ProxySQLで管理されているセッションの Connection Id を確認するには、ProxySQLの管理者用インターフェースに接続して、SHOW PROCESSLIST を実行します。 (SHOW PROCESSLIST コマンドを使う点は MySQL と同じですが、出力される項目が MySQL と少し違いますね)

$ mysql -h127.0.0.1 -P6032 -uadmin -padmin
mysql> SHOW PROCESSLIST;
+-----------+<snip>+---------+-----------------------------------------+
| SessionID |<snip>| time_ms | info                                    |
+-----------+<snip>+---------+-----------------------------------------+
| 2         |<snip>| 30030   | NULL                                    |
| 11        |<snip>| 0       | SELECT SLEEP(100), user FROM mysql.user |
+-----------+<snip>+---------+-----------------------------------------+
2 rows in set (0.00 sec)

ProxySQL の Connection ID (Session ID) 11 を指定してKILLすることで、MySQLの Id 713 を KILL 出来ました。

mysql> SHOW PROCESSLIST;
+-----+-----------------+<snip>+-----------------------------------------+
| Id  | User            |<snip>| Info                                    |
+-----+-----------------+<snip>+-----------------------------------------+
|   6 | system user     |<snip>| NULL                                    |
|   7 | event_scheduler |<snip>| NULL                                    |
|  10 | system user     |<snip>| NULL                                    |
|  11 | system user     |<snip>| NULL                                    |
|  12 | system user     |<snip>| NULL                                    |
|  13 | system user     |<snip>| NULL                                    |
| 659 | root            |<snip>| NULL                                    |
| 692 | root            |<snip>| SHOW PROCESSLIST                        |
| 713 | root            |<snip>| SELECT SLEEP(100), user FROM mysql.user |
+-----+-----------------+<snip>+-----------------------------------------+
9 rows in set, 1 warning (0.00 sec)

mysql> KILL 11;
Query OK, 0 rows affected (0.00 sec)

-- 713 がいなくなった
mysql> SHOW PROCESSLIST;
+-----+-----------------+<snip>+------------------+
| Id  | User            |<snip>| Info             |
+-----+-----------------+<snip>+------------------+
|   6 | system user     |<snip>| NULL             |
|   7 | event_scheduler |<snip>| NULL             |
|  10 | system user     |<snip>| NULL             |
|  11 | system user     |<snip>| NULL             |
|  12 | system user     |<snip>| NULL             |
|  13 | system user     |<snip>| NULL             |
| 659 | root            |<snip>| NULL             |
| 692 | root            |<snip>| SHOW PROCESSLIST |
+-----+-----------------+<snip>+------------------+
8 rows in set, 1 warning (0.00 sec)

なお、KILL QUERY も同様に、ProxySQL の Connection Id を指定する必要があります。

ProxySQL を複数利用している場合の注意点

Connection ID (Session ID) は、ProxySQLサーバーごとに管理されています。ある接続をKILLしたいときは、その接続を実際に処理しているProxySQLインスタンスに接続してKILLコマンドを実行しなければなりません。 複数のProxySQLインスタンスロードバランサーの下で運用している場合、接続した先のProxySQLが該当の接続を担当している ProxySQL とは異なる ProxySQLインスタンスである可能性があります。

KILLする際は、ロードバランサ等を介さずに、各ProxySQLの管理者インタフェースに直接接続して KILL コマンドを実行するのが良いでしょう。 しかし、そうするには、どのProxySQLが目的の接続を処理しているのかを特定する必要があり、ProxySQLを介した、KILLのオペレーションは どうやっても煩雑になりそうです。

💡管理者インターフェイスでも KILL コマンドを使うことができます。ただし、管理者インタフェースでは KILL CONNECTIONCONNECTION を省略せずに書く必要がある。

mysql> KILL 15;
ERROR 1045 (28000): ProxySQL Admin Error: near "KILL": syntax error

mysql> KILL CONNECTION 15;
Query OK, 0 rows affected (0.00 sec)

まとめ

  • ProxySQLを介して、KILLするとややこしいので、Backend の MySQLに直接接続して KILLするのが一番簡単で確実!