CLOVER🍀

That was when it all began.

MySQL 8.0.22以降は、show [full] processlist文ではなくperformance_schemaのprocesslistテーブルを使う

これは、なにをしたくて書いたもの?

MySQLを使っていてトラブルがあった時によく使うコマンドのひとつとして、show [full] processlistがあると思います。

ただ、これはMySQL 8.0.22以降は代替の方法を使うように促されています。

今回はその内容を確認したいと思います。要は知識のアップデートです。

show [full] processlist文

現在のMySQL 8.0のshow [full] processlist文のページを見ると、MySQL 8.0.22以降はprocesslistテーブルを使うように示唆されています。

MySQL 8.0.22 の時点では、SHOW PROCESSLIST の代替実装はパフォーマンススキーマ processlist テーブルに基づいて使用できます。これは、デフォルトの SHOW PROCESSLIST 実装とは異なり、mutex を必要とせず、パフォーマンス特性が向上します。 詳細は、セクション27.12.19.9「processlist テーブル」を参照してください。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 13.7.7.29 SHOW PROCESSLIST ステートメント

MySQL 8.0.22のリリースノートにも書かれています。

Changes in MySQL 8.0.22 (2020-10-19, General Availability) / Performance Schema Notes

グローバルなmutexを取るので、リソースビジーなシステムではパフォーマンスに悪影響があるから、ということですね。

The SHOW PROCESSLIST statement provides process information by collecting thread data from all active threads. However, because the implementation iterates across active threads from within the thread manager while holding a global mutex, it has negative performance consequences, particularly on busy systems.

ちなみに、show [full] processlist文がアクセスしているのはinformation_schemaprocesslistテーブルのようです。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 26.23 INFORMATION_SCHEMA PROCESSLIST テーブル

では、MySQL 8.4のドキュメントを見てみます。

show [full] processlist文は非推奨だという記述に変わっています。

The INFORMATION SCHEMA implementation of SHOW PROCESSLIST is deprecated and subject to removal in a future MySQL release. It is recommended to use the Performance Schema implementation of SHOW PROCESSLIST instead.

MySQL :: MySQL 8.4 Reference Manual :: 15.7.7.31 SHOW PROCESSLIST Statement

performance_schema.processlistテーブル

代替手段は、performance_schemaprocesslistですね。

MySQL :: MySQL 8.4 Reference Manual :: 29.12.22.7 The processlist Table

MySQL 8.0でも使えます。

MySQL :: MySQL 8.0 リファレンスマニュアル :: 27.12.19.9 processlist テーブル

performance_schema.processlistテーブルは直接クエリーを投げることができ、process権限があればすべてのスレッドの情報を
見ることができます。process権限を持たない場合は自ユーザーのスレッドに関する情報のみにアクセスできるようです。

The processlist table can be queried directly. If you have the PROCESS privilege, you can see all threads, even those belonging to other users. Otherwise (without the PROCESS privilege), nonanonymous users have access to information about their own threads but not threads for other users, and anonymous users have no access to thread information.

このあたりはshow [full] processlist文と同じですね。

ちなみにシステム変数performance_schema_show_processlistonにすると、show [full] processlistのアクセス先を
performance_schema.processlistテーブルに切り替えることができるようです。

Performance Schema System Variables / performance_schema_show_processlist

ただシステム変数performance_schema_show_processlist自体が非推奨なので、performance_schema.processlistテーブルを
使った方がよいでしょうね。

あとは実際に少し動かして確認してみましょう。

環境

今回の環境はこちら。

 MySQL  localhost:3306 ssl  practice  SQL > select version();
+-----------+
| version() |
+-----------+
| 8.4.3     |
+-----------+
1 row in set (0.0007 sec)

performance_schema.processlistテーブルを使う

単純にperformance_schema.processlistテーブルにselect文を実行するだけですが。

 MySQL  localhost:3306 ssl  practice  SQL > select * from performance_schema.processlist\G
*************************** 1. row ***************************
              ID: 14
            USER: kazuhira
            HOST: 127.0.0.1:36710
              DB: practice
         COMMAND: Query
            TIME: 0
           STATE: executing
            INFO: select * from performance_schema.processlist
EXECUTION_ENGINE: PRIMARY
*************************** 2. row ***************************
              ID: 16
            USER: kazuhira
            HOST: 127.0.0.1:44508
              DB: practice
         COMMAND: Sleep
            TIME: 2447
           STATE:
            INFO: NULL
EXECUTION_ENGINE: PRIMARY
*************************** 3. row ***************************
              ID: 18
            USER: kazuhira
            HOST: 127.0.0.1:58888
              DB: practice
         COMMAND: Sleep
            TIME: 4
           STATE:
            INFO: NULL
EXECUTION_ENGINE: PRIMARY
3 rows in set (0.0009 sec)

select * from performance_schema.processlistを実行している接続と合わせて、他に2つ接続しています。

それぞれでsleepを実行してみましょう。

 MySQL  localhost:3306 ssl  practice  SQL > select sleep(10);

クエリーが見えますね。

 MySQL  localhost:3306 ssl  practice  SQL > select * from performance_schema.processlist\G
*************************** 1. row ***************************
              ID: 14
            USER: kazuhira
            HOST: 127.0.0.1:36710
              DB: practice
         COMMAND: Query
            TIME: 0
           STATE: executing
            INFO: select * from performance_schema.processlist
EXECUTION_ENGINE: PRIMARY
*************************** 2. row ***************************
              ID: 16
            USER: kazuhira
            HOST: 127.0.0.1:44508
              DB: practice
         COMMAND: Query
            TIME: 4
           STATE: User sleep
            INFO: select sleep(10)
EXECUTION_ENGINE: PRIMARY
*************************** 3. row ***************************
              ID: 18
            USER: kazuhira
            HOST: 127.0.0.1:58888
              DB: practice
         COMMAND: Query
            TIME: 3
           STATE: User sleep
            INFO: select sleep(10)
EXECUTION_ENGINE: PRIMARY
3 rows in set (0.0009 sec)

ところで、fullをつけないshow processlist文はクエリーの内容が100文字で切られてしまうのでした。
performance_schema.processlistテーブルではどうなるのかも一応確認しておきましょう。

他の2つの接続のうちのひとつで、こんなSQL文を実行しておきます。

 MySQL  localhost:3306 ssl  practice  SQL > select sleep(10) /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa---end */;

確認。

 MySQL  localhost:3306 ssl  practice  SQL > select * from performance_schema.processlist\G
*************************** 1. row ***************************
              ID: 14
            USER: kazuhira
            HOST: 127.0.0.1:36710
              DB: practice
         COMMAND: Query
            TIME: 0
           STATE: executing
            INFO: select * from performance_schema.processlist
EXECUTION_ENGINE: PRIMARY
*************************** 2. row ***************************
              ID: 16
            USER: kazuhira
            HOST: 127.0.0.1:44508
              DB: practice
         COMMAND: Query
            TIME: 2
           STATE: User sleep
            INFO: select sleep(10)
EXECUTION_ENGINE: PRIMARY
*************************** 3. row ***************************
              ID: 18
            USER: kazuhira
            HOST: 127.0.0.1:58888
              DB: practice
         COMMAND: Query
            TIME: 4
           STATE: User sleep
            INFO: select sleep(10) /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa---end */
EXECUTION_ENGINE: PRIMARY
3 rows in set (0.0009 sec)

OKですね。

おわりに

MySQLshow [full] processlistの代わりにperformance_schema.processlistテーブルを使ってみました。

この情報はなんとなく前々から知ってはいたのですが、ちゃんと意識的に切り替えるようにしていなかったので、この機会に1度ちゃんと
見ておこうかなということでした。