はじめに
MySQL 8.0.22 がリリースされてしばらく経ちましたが、読み直している際にひとつ気になる内容を見つけました。
An alternative SHOW PROCESSLIST implementation is now available based on the new Performance Schema processlist table. This implementation queries active thread data from the Performance Schema rather than the thread manager and does not require a mutex:
参照: Performance Schema Notes
新しくパフォーマンススキーマに processlist テーブルが追加されて、今後は SHOW PROCESSLIST
コマンドを実行する際に、INFORMATION_SCHEMA.PROCESSLIST テーブルではなく、peformance_schema.processlist テーブルから情報を取得できるようになる機能が追加されたようです。
今までにも何度か INFORMATION_SCHEMA からパフォーマンススキーマへとテーブルが移行されたことはありましたが、どのような情報が移行されてきたのか、今回は改めてバージョンを追いながら確認していきたいと思います。
システム変数およびステータス変数
まず、MySQL5.7 がリリースされたときに、 SHOW [GLOBAL] VARIABLES
と SHOW [GLOBAL] STATUS
コマンドで参照するテーブルがパフォーマンススキーマに移行されました。
- MySQL5.6 以前
1 2 3 4 5 |
INFORMATION_SCHEMA.GLOBAL_VARIABLES INFORMATION_SCHEMA.SESSION_VARIABLES INFORMATION_SCHEMA.GLOBAL_STATUS INFORMATION_SCHEMA.SESSION_STATUS |
- MySQL5.7 以降
1 2 3 4 5 6 7 8 9 10 |
performance_schema.global_variables performance_schema.session_variables performance_schema.variables_by_thread performance_schema.global_status performance_schema.session_status performance_schema.status_by_thread performance_schema.status_by_account performance_schema.status_by_host performance_schema.status_by_user |
MySQL8.0 では既に INFORMATION_SCHEMA のテーブルは削除されていますが、MySQL5.7 では後方互換性のために show_compatibility_56 というシステム変数を有効にすることで、従来通り INFORMATION_SCHEMA のテーブル情報を参照させることができました。
移行された経緯については WL#6629 に詳細が記載されており、セッション変数の値の累計などに関する要望やバグに対応するためだったようです。
なお、SHOW [GLOBAL] STATUS
コマンドと performance_schema.{global|session}_status テーブルは、以下のように取得件数が異なっています。
1 2 3 4 5 6 7 |
mysql> SHOW GLOBAL STATUS; (...) 474 rows in set (0.01 sec) mysql> SELECT * FROM performance_schema.global_status; (...) 304 rows in set (0.01 sec) |
これは、パフォーマンススキーマ上では Com_xxx のステータス変数が集計されていないためであり、これらの統計情報を取得する場合は、events_statements_summary_global_by_event_name テーブルや events_statements_summary_by_thread_by_event_name テーブルから、以下のようなクエリを実行して確認することができます。
1 2 3 |
mysql> SELECT EVENT_NAME,COUNT_STAR FROM performance_schema.events_statements_summary_global_by_event_name WHERE EVENT_NAME LIKE 'statement/sql/%'; |
ロック情報
MySQL8.0 になると、今まで INFORMATION_SCHEMA で参照していた InnoDB の行ロック情報のテーブルが削除され、パフォーマンススキーマ上でロック情報を確認できるようになりました。
- MySQL5.7 以前
1 2 |
INFORMATION_SCHEMA.INNODB_LOCKS INFORMATION_SCHEMA.INNODB_LOCK_WAITS |
- MySQL8.0 以降
1 2 |
performance_schema.data_lock_waits performance_schema.data_locks |
なお、競合している行ロック情報を出力する sys スキーマの innodb_lock_waits ビューは MySQL8.0 からパフォーマンススキーマを参照するように変更されているため、普段こちらのテーブルを使用している場合は特に意識する必要はありません。
変更の経緯は WL#9275 に詳細が記載されており、競合しているロック以外も確認できるようにしつつ、InnoDB 以外のストレージエンジンにも対応できるようにするためだったようです。
また、この data_locks テーブル には現在取得されているすべてのテーブルロックや行ロックが取得されるので、クエリの検証などをおこなう際には想定外のギャップロックなども確認することができるため、単一で使用する際にも便利かと思います。
1 2 3 4 5 6 7 |
mysql> SELECT * FROM performance_schema.data_locks; (...)+------------+-(...)+-----------+-----------+-------------+------------------------+ (...)| INDEX_NAME | (...)| LOCK_TYPE | LOCK_MODE | LOCK_STATUS | LOCK_DATA | (...)+------------+-(...)+-----------+-----------+-------------+------------------------+ (...)| NULL | (...)| TABLE | IX | GRANTED | NULL | (...)| PRIMARY | (...)| RECORD | X | GRANTED | supremum pseudo-record | (...)+------------+-(...)+-----------+-----------+-------------+------------------------+ |
プロセスリスト(スレッド接続情報)
10 月にリリースされた MySQL8.0.22 では、パフォーマンススキーマに processlist テーブルが追加され、 SHOW PROCESSLIST
コマンドで参照するテーブルを INFORMATION_SCHEMA から変更することができるようになりました。
- MySQL8.0.21 以前
1 |
INFORMATION_SCHEMA.PROCESSLIST |
- MySQL8.0.22 以降
1 |
peformance_schema.processlist |
挙動は performance_schema_show_processlist で変更することが可能で、MySQL8.0.22 現在、デフォルトでは OFF になっています。
なお、有効にした場合は、以下のパラメータをデフォルトにしておかないと情報が途切れてしまい、従来の表示と互換性が失われる可能性があるので注意する必要があります。
- performance_schema_max_thread_instances
- performance_schema_max_thread_classes
- performance_schema_max_stage_classes
変更の経緯は WL#9090 に詳細が記載されており、負荷の高いときには INFORMATION_SCHEMA.PROCESSLIST テーブルを参照する際に取得される mutex ロックが原因で、パフォーマンス劣化につながる可能性を回避するためだったようです。
また、パフォーマンススキーマでは以前から threads テーブルからバッググラウンドの処理を含めたスレッド情報が取得可能です。こうしたテーブルから現在の(フォアグラウンドの)プロセスリストを表示する際には、sys スキーマの processlist ビューや session ビューを参照することで、同様にパフォーマンススキーマから情報を取得することができます。
まとめ
ここまで、INFORMATION_SCHEMA からパフォーマンススキーマへ移行されてきた情報について確認しました。
パフォーマンススキーマに移行されることでパフォーマンスの向上や取得情報の拡張などがおこなわれるのは嬉しいですが、もしパフォーマンススキーマを無効にしてしまうと、ステータス変数やシステム変数(global_variables, session_variables, global_status, and session_status)以外のテーブルは更新されなくなるため、パフォーマンススキーマを有効にすることがほぼ必須となってくる点にはご注意ください。
また、どうやら MySQL では、頻繁に更新される情報をなるべく INFORMATION_SCHEMA 上に保持しないようにする変更を進めているようです。このまま情報の分離が進んでいけば、いずれは INFORMATION_SCHEMA ストレージエンジンが実装される日がくるかもしれませんね。
参考
27.12.15 Performance Schema Status Variable Tables
15.15.2 InnoDB INFORMATION_SCHEMA Transaction and Locking Information
27.12.19.6 The processlist Table