はじめに
2025-10-21 にリリースされた MySQL Server 9.5 において、mysqldm(MySQL Diagnostic Monitor) コマンドが新しく実装されました。
This version includes the MySQL Diagnostic Monitor (mysqldm), a new client tool designed to collect server diagnostic information. (…)
Note
MySQL Diagnostic Monitor is only available with MySQL Enterprise Edition.参照 : Changes in MySQL 9.5.0 (2025-10-21, Innovation Release)
今回はこのコマンドの仕様や注意点について紹介していきたいと思います。
なお、この機能は 2026 年 2 月の時点で、 MySQL Enterprise Edition でのみ使用可能 な点にご注意ください。
概要
mysqldm コマンドは MySQL サーバーの診断データを収集するクライアントツールです。診断用のクエリを定期的に実行して、その結果を JSON ファイルとして出力してくれます。
参照 : 6.5.8 mysqldm — The MySQL Diagnostic Monitor
また、mysql-client パッケージに同梱されており、リモートサーバーに対しても使用することが可能です。
既に存在する同様の機能としては、 sys.diagnostics() プロシージャが挙げられます。こちらと比較すると、以下のような違いがあります。
- 出力結果は JSON 形式のファイルとして出力される
- sys.diagnostics() プロシージャは表形式で出力されて、その内容は別途
teeで書き出す必要があります
- sys.diagnostics() プロシージャは表形式で出力されて、その内容は別途
- 取得できる情報が多い
- sys.diagnostics() では、ロック関連情報やレプリケーション関連情報は取得されません
なお、本番環境で実行する際はピーク時間帯を避けて、事前にストレージ容量を確認しておくことを推奨します。
検証環境
今回は、以下の環境で検証をおこないました。
- Rocky Linux release 9.6 (Blue Onyx)
- MySQL Enterprise Server 9.6.0-commercial for Linux on x86_64
使用方法
コマンドの実行例および主要なオプションは以下の通りです。なお、このツールはクライアントコマンドであるため、接続文字列や汎用オプションについては説明を省いています。
参照 : 6.5.8.1 Options
|
1 2 3 |
(コマンド例) [root@test]# mysqldm -u username -h hostname -p --iterations=10 --delay=30 --output-dir=dirname |
- --iterations
- 診断クエリを反復実行する回数を指定します。デフォルト値は 10 です
- --delay
- 診断クエリを実行する間隔(秒)を指定します。デフォルト値は 30 です
- --output-dir
- クエリの結果が格納されるディレクトリ名を指定します。デフォルトではカレントディレクトリに生成されます
- ディレクトリを指定する場合、事前に該当ディレクトリを作成しておく必要があるのでご注意ください
|
1 2 3 4 |
[root@test]# mysqldm -u root -h localhost -p --iterations=5 --delay=1 --output-dir=result_dir Enter password: mysqldm: Failed to create dm/mysqldmtemp: No such file or directory |
これ以外のオプションの詳細はリファレンスあるいは --help オプションで確認することが可能です。
なお、執筆時点(2026 年 3 月)において、mysqldm コマンドの man ページは未登録でした。
|
1 2 3 |
[root@test]# man mysqldm No manual entry for mysqldm |
出力内容
コマンドの実行中に標準出力へのメッセージはおこなわれないため、進捗状況については確認することが出来ない点にご注意ください。
なお、コマンドの実行中のみ、 --output-dir 内に mysqldmtemp ディレクトリが作成されるため、生成されているファイルの数から間接的に状況を確認することが可能です。
|
1 2 3 4 5 6 7 8 9 |
[root@test]# ls -l mysqldmtemp total 1608 -rw-r--r-- 1 root root 138 Feb 27 00:34 available_storage_engines.json -rw-r--r-- 1 root root 67 Feb 27 00:34 engine_summary.json -rw-r--r-- 1 root root 138 Feb 27 00:34 engine_support.json -rw-r--r-- 1 root root 85 Feb 27 00:34 engine_table_usage_summary.json -rw-r--r-- 1 root root 2071 Feb 27 00:34 error_log.json (...) |
実行した結果は、自動で zip 形式に圧縮されて保存されます。
|
1 2 3 4 5 6 |
[root@test]# mysqldm -u root -h localhost -p --iterations=5 --delay=1 Enter password: [root@test]# ls -l total 184 -rw-r--r-- 1 root root 184641 Feb 27 00:34 mysqldm-20260226153442.zip |
各ファイルの内容については、クエリの実行結果が QueryOutput というキーに配列としてまとめられており、その内部の ResultSet に具体的な行データが配列形式で格納されています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
[root@test]# cat show_full_processlist.json | jq { "QueryOutput": [ { "ResultSet": [ [ "5", "event_scheduler", "localhost", null, "Daemon", "104400", "Waiting on empty queue", null ], [ "8433", "root", "localhost", null, "Query", "0", "init", "SHOW FULL PROCESSLIST" ] ] } ] } |
収集される診断クエリは、「コマンド実行時に 1 回のみ取得されるクエリ」と、その後「定期的に取得されるクエリ」の 2 種類があります。
ファイル名の詳細については以下のリファレンスをご確認ください。
参照 : 6.5.8.2 Diagnostic Queries
それぞれのクエリの詳細については以下の通りです。
コマンド実行時に 1 回のみ取得されるクエリ
サーバーシステム変数やテーブル情報、レプリケーションやパフォーマンススキーマの設定などを含めて、基本的な設定関連の情報が取得されます。
なお、ユーザー情報やインデックス統計などは取得されていないようです。
- 取得時刻 :
SELECT NOW() - インスタンスの基本情報類 : クエリの詳細はこちら
- サーバーのバージョン情報やタイムゾーン、実行ユーザーなどが表示されます
- サーバーシステム変数関連情報
- サーバーシステム変数一覧 :
SHOW GLOBAL VARIABLES - 各サーバーシステム変数の値が設定された方法 : クエリの詳細はこちら
- サーバーシステム変数一覧に加えて、
VARIABLE_SOURCEカラム(変更した方法)が追加で表示されます
- サーバーシステム変数一覧に加えて、
- 永続化されているシステム変数(mysqld-auto.cnf) :
SELECT * FROM PERFORMANCE_SCHEMA.PERSISTED_VARIABLES
- サーバーシステム変数一覧 :
- 各スキーマのテーブル数 : クエリの詳細はこちら
- 各スキーマのストアドルーチン数 : クエリの詳細はこちら
- error_log テーブル(エラーログ) :
SELECT * FROM PERFORMANCE_SCHEMA.ERROR_LOG - host_cache テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.HOST_CACHE - 使用可能なストレージエンジン一覧 :
select engine from information_schema.engines where support<>'NO'- なぜか同じ情報を取得している、
available_storage_engines.jsonとengine_support.jsonという異なる名前のファイルが 2 つ存在しています
- なぜか同じ情報を取得している、
- ストレージエンジン概要 : クエリの詳細はこちら
- InnoDB ストレージエンジンやパフォーマンススキーマが有効になっているかどうかや、レプリケーションが作成されているかどうかを確認します
has_p_s_replicationというカラムは、パフォーマンススキーマにレプリケーション関連テーブル(replication_*)が存在しているかどうかを判断するものと思われますが、リファレンス上だとhas_performance_schemaと同じ判断条件になっているため、実際にどのような挙動が想定されているかは不明です
- ストレージエンジン毎のテーブル統計 : クエリの詳細はこちら
- テーブル数、データおよびインデックスの合計サイズをストレージエンジン毎に出力します
- レプリケーション関連情報
- replication_applier_configuration テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_APPLIER_CONFIGURATION - replication_applier_filters テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_APPLIER_FILTERS - replication_applier_status テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_APPLIER_STATUS - replication_applier_status_by_coordinator テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_APPLIER_STATUS_BY_COORDINATOR - replication_applier_status_by_worker テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_APPLIER_STATUS_BY_WORKER - replication_asynchronous_connection_failover テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_ASYNCHRONOUS_CONNECTION_FAILOVER - replication_asynchronous_connection_failover_managed テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_ASYNCHRONOUS_CONNECTION_FAILOVER_MANAGED - replication_connection_configuration テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_CONNECTION_CONFIGURATION - replication_connection_status テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_CONNECTION_STATUS - replication_group_member_stats テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_GROUP_MEMBER_STATS - replication_group_members テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.REPLICATION_GROUP_MEMBERS
- replication_applier_configuration テーブル :
- パフォーマンススキーマ関連情報
- パフォーマンススキーマの内部ステータス(SHOW ENGINE コマンド) :
SHOW ENGINE PERFORMANCE_SCHEMA STATUS - setup_actors テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.SETUP_ACTORS - setup_objects テーブル :
SELECT * FROM PERFORMANCE_SCHEMA.SETUP_OBJECTS - setup_consumers テーブル :
SELECT NAME AS CONSUMER, ENABLED, SYS.PS_IS_CONSUMER_ENABLED(NAME) AS COLLECTS FROM PERFORMANCE_SCHEMA.SETUP_CONSUMERS - setup_instruments テーブル : クエリの詳細はこちら
- 該当テーブルに対して
SUBSTRING_INDEXカラムで集計がおこなわれています
- 該当テーブルに対して
- threads テーブル : クエリの詳細はこちら
- 該当テーブルに対して
TYPEカラムで集計がおこなわれています
- 該当テーブルに対して
- パフォーマンススキーマの内部ステータス(SHOW ENGINE コマンド) :
sysスキーマ- schema_object_overview ビュー :
SELECT * FROM SYS.SCHEMA_OBJECT_OVERVIEW - host_summary ビュー :
SELECT * FROM SYS.HOST_SUMMARY - schema_unused_indexes ビュー :
SELECT * FROM SYS.SCHEMA_UNUSED_INDEXES WHERE OBJECT_SCHEMA NOT IN ('PERFORMANCE_SCHEMA', 'SYS', 'MYSQL', 'INFORMATION_SCHEMA')
- schema_object_overview ビュー :
- PREPARED 状態の XA トランザクション :
XA RECOVER CONVERT XID
また、リファレンスには記載されていませんが、MySQL Server 9.1 から Enterprise Edition でのみ実装されているオプショントラッカーコンポーネント(component_option_tracker) の mysql_option.option_usage テーブルに関する情報も取得されているようです。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# cat option_usage.json | jq { "QueryOutput": [ { "ResultSet": [ [ "", "", "Berry Picker", "{\"used\": true, \"usedDate\": \"2024-10-17T20:38:23Z\"}" ] ] } ] } |
定期的に取得されるクエリ
サーバーステータス変数やプロセスリスト、レプリケーションの状態や各種ロック情報など、動的に変化する情報が取得されています。
- 取得時刻 :
SELECT NOW() - サーバーステータス変数一覧 :
SHOW GLOBAL STATUS - プロセスリスト :
SHOW FULL PROCESSLIST - テーブルキャッシュ内のテーブル情報 :
SHOW OPEN TABLES - トランザクション一覧情報 :
SELECT * FROM information_schema.innodb_trx - InnoDB 関連情報
- InnoDB 標準モニター情報 :
SHOW ENGINE INNODB STATUS - INNODB_METRICS テーブル :
SELECT * FROM information_schema.innodb_metrics
- InnoDB 標準モニター情報 :
- バイナリログファイル関連情報
- 現在のバイナリログファイル(ポジション)情報 :
SHOW BINARY LOG STATUS - バイナリログファイル一覧 :
SHOW BINARY LOGS
- 現在のバイナリログファイル(ポジション)情報 :
- レプリケーション関連情報
- レプリカの一覧 :
SHOW REPLICAS - レプリカの設定情報 :
SHOW REPLICA STATUS - 接続メタデータリポジトリ(slave_master_info テーブル) :
SELECT * FROM mysql.slave_master_info ORDER BY Channel_name - 適用者メタデータリポジトリ(slave_relay_log_info テーブル) :
SELECT Channel_name, Sql_delay, Number_of_workers, Id FROM mysql.slave_relay_log_info ORDER BY Channel_name
- レプリカの一覧 :
- sys スキーマ
- metrics ビュー :
SELECT * FROM sys.metrics - ロック待機系
- innodb_lock_waits ビュー :
SELECT * FROM sys.innodb_lock_waits - schema_table_lock_waits ビュー :
SELECT * FROM sys.schema_table_lock_waits
- innodb_lock_waits ビュー :
- セッション情報系
- session_ssl_status ビュー :
SELECT * FROM sys.session_ssl_status - session ビュー :
SELECT * FROM sys.session - processlist ビュー :
SELECT * FROM sys.processlist
- session_ssl_status ビュー :
- メモリー系
- memory_global_by_current_bytes ビュー :
SELECT * FROM sys.memory_global_by_current_bytes - memory_by_thread_by_current_bytes ビュー :
SELECT * FROM sys.memory_by_thread_by_current_bytes - memory_by_host_by_current_bytes ビュー :
SELECT * FROM sys.memory_by_host_by_current_bytes - memory_by_user_by_current_bytes ビュー :
SELECT * FROM sys.memory_by_user_by_current_bytes
- memory_global_by_current_bytes ビュー :
- metrics ビュー :
- パフォーマンススキーマ関連情報
- events_waits_current テーブル :
SELECT * FROM performance_schema.events_waits_current - events_statements_summary_global_by_event_name テーブル :
SELECT * FROM performance_schema.events_statements_summary_global_by_event_name - threads テーブル :
SELECT * FROM performance_schema.threads - metadata_locks テーブル :
SELECT * FROM performance_schema.metadata_locks
- events_waits_current テーブル :
実行に必要な権限
必要な権限についてリファレンス上は明記されていませんが、検証をおこなったところ、以下の権限が必要であることがわかりました。
なお、sys と performance_schema データーベースについては、今後参照テーブルが増えることを想定してすべてのテーブルに対して権限を付与しています。
performance_schema.*に対するSELECT権限sys.*に対するSELECTとEXECUTE権限mysql_option.*に対するSELECT権限mysql.slave_master_infoとmysql.slave_relay_log_infoに対するSELECT権限- 以下の GLOBAL および動的権限
OPTION_TRACKER_UPDATERあるいはOPTION_TRACKER_OBSERVERPROCESSREPLICATION CLIENTREPLICATION SLAVEXA_RECOVER_ADMIN
また、クエリが実行できない場合でも mysqldm コマンド自体はエラーになりません。
実行後の各ファイルを確認すると、実行できなかったクエリについては結果の代わりにエラーの詳細が記載されていることがわかります。
|
1 2 3 4 5 6 7 8 9 10 11 |
[root@test]# cat ./show_binary_log_status.json | jq { "QueryOutput": [ { "SQLError": "Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation", "SqlState": "42000", "SqlErrno": 1227 } ] } |
注意点
実際に何回か使用してみたところ、いくつか気になる箇所がありました。
各ファイルは 1 回分の取得結果しか保持していない
定期的に取得されるクエリであっても、各ファイルは 1 回分の取得結果のみを保持します。そのため、--iterations に 2 以上を指定した場合、1 回目は [ファイル名].json、2 回目は [ファイル名]1.json、のように出力されます。
また、各ファイル内には情報取得時刻が保存されていません。そのため、クエリが実行された時刻を確認したい場合、取得時刻を格納したファイル(nowN.json)と突合する必要があります。
情報の取得タイミングと実行間隔が直感的でない
定期的に取得されるクエリは、コマンド実行時に 1 回のみ取得されるクエリと同じタイミングで、1 回目の取得がおこなわれます。
また、--delay による待機がおこなわれた後で --iterations のチェックがおこなわれているため、コマンドの終了タイミングに 1 回分のズレがあります。
--iterations=2, --delay=30 で取得した場合の例
カラム名は取得されない
各クエリの実行結果にはカラム名が取得されていません。
そのため、以下のように何のクエリの結果であるか不明なファイルについては、実行されたクエリをその都度確認する必要があります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
[root@test]# cat instance_summary.json | jq { "QueryOutput": [ { # ※以下のコメント部分は手動で追記しています "ResultSet": [ # [実行されているクエリ] [ # SELECT "test", # @@GLOBAL.HOSTNAME AS `HOSTNAME`, "3306", # @@GLOBAL.PORT AS `PORT`, null, # @@GLOBAL.REPORT_HOST AS `REPORT HOST`, "3306", # @@GLOBAL.REPORT_PORT AS `REPORT PORT`, "/var/lib/mysql/mysql.sock", # @@GLOBAL.SOCKET AS `SOCKET`, "/var/lib/mysql/", # @@GLOBAL.DATADIR AS `DATADIR`, "7290fa1b-12fd-11f1-88c9-000c2911c006", # @@GLOBAL.SERVER_UUID AS `SERVER UUID`, "1", # @@GLOBAL.SERVER_ID AS `SERVER_ID`, "9.6.0-commercial", # VERSION() AS `MYSQL VERSION`, "2.1.3", # (SELECT SYS_VERSION FROM SYS.VERSION) AS `SYS SCHEMA VERSION`, "MySQL Enterprise Server - Commercial", # @@GLOBAL.VERSION_COMMENT AS `VERSION COMMENT`, "Linux", # @@GLOBAL.VERSION_COMPILE_OS AS `VERSION COMPILE OS`, "x86_64", # @@GLOBAL.VERSION_COMPILE_MACHINE AS `VERSION COMPILE MACHINE`, "2026-02-27 15:25:22", # UTC_TIMESTAMP() AS `UTC TIME`, "2026-02-28 00:25:22", # NOW() AS `LOCAL TIME`, "SYSTEM", # @@TIME_ZONE AS `TIME ZONE`, "JST", # @@SYSTEM_TIME_ZONE AS `SYSTEM TIME ZONE`, "09:00:00" # CAST(TIMEDIFF(NOW(), UTC_TIMESTAMP()) AS CHAR) AS `TIME ZONE OFFSET`) ] ] } ] } |
利用例
本機能は高負荷時の診断情報の取得を目的として設計されているため、MySQL Server を監視する際に利用されることが想定されています。
従来の監視系ツールと比較すると、以下の部分で差別化がおこなわれています。
リモートサーバーでの実行が可能
取得している情報はすべて SELECT 系のコマンドであるため、リモートサーバー上で実行することが可能です。これにより、取得したログファイルはサーバー側のディスクを圧迫しません。
また、現時点では実行することでパフォーマンス影響のあるクエリは見受けられないので、環境やデータ量にも依存しますが、低負荷で実行できるのではないかと思われます。
ただし、innodb_trx テーブルなど、環境によっては結果が非常に大きくなる可能性があるクエリも存在するため、実行しても問題がないかは事前に確認しておくことを推奨いたします。
OS 側の負荷情報は取得されない
MySQL の内部負荷情報を確認することはできますが、OS 側のリソース使用情報については一切取得されていません。
そのため、実際にログの分析をおこなう場合は、vmstat などの情報を別途取得するか、既存の監視ツールとあわせて調査する必要がある点にご注意ください。
連携の容易性
ファイルはすべて JSON 形式で保存されているため、直接ファイルを確認する際の視認性はあまり良くないですが、API などへの連携がしやすくなっています。
たとえば以下のように、 show_global_statusN.json ファイルの値を取得時刻毎に並べて、CSV 形式に変換することも容易です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#/bin/bash out="global_status_all.csv" # 1) すべてのキーを JSON 配列として作る keys_json=$( jq -s ' [.[].QueryOutput[0].ResultSet[][0]] | unique | sort ' show_global_status*.json ) # 2) ヘッダを @csv で生成 jq -nr --argjson keys "$keys_json" ' ["timestamp"] + $keys | @csv ' > "$out" # 3) 各行を出力 for f in now*.json; do suffix=${f#now} status_file="show_global_status${suffix}" jq -r \ --argjson keys "$keys_json" \ --slurpfile nowfile "$f" ' ($nowfile[0].QueryOutput[0].ResultSet[0][0]) as $ts | (.QueryOutput[0].ResultSet | map({(.[0]): .[1]}) | add) as $o | ([$ts] + ($keys | map($o[.] // ""))) | @csv ' "$status_file" >> "$out" done |
まとめ
ここまで、mysqldm コマンドの使い方や仕様について確認してきました。
これほどまでに MySQL サーバーの詳細情報を取得できるのは、他の監視ツールにはなかった機能です。なお、まだイノベーションリリースでの実装であるためか、情報の重複や一部仕様に気になる点があったので今後の改良にも期待したいと思います。
また、負荷の原因調査の際などは、基本的に情報は取得しすぎても困ることはないため、コマンド 1 つで網羅的に確認できるのは便利ではないかと思います。今後は弊社のサポートにおいても、取得をご依頼させていただくことがあるかもしれません。
Enterprise Edition でのみ使用可能な点は残念ですが、使用できる方は今後の調査の際に是非活用してみてはいかがでしょうか。



