はじめに
データベース運用において、性能の問題やトラブルの原因を特定するためのトラブルシューティングは、日々の業務で避けて通れない重要な作業です。しかし、複雑化するシステム環境や増大するデータ量の中で、何が問題の原因なのかを見つけるのは容易ではありません。MySQL Shellにはパフォーマンス問題やシステムの異常を検出し、原因特定を支援するためのツールとして
本記事では、MySQL Shellの診断ユーティリティを活用して、実際の運用環境で起こり得るトラブルをどのように効率的に解決できるかを解説します。具体的には、以下の3つの主要な診断ユーティリティに焦点を当てます。
-
util.
debug. collectDiagnostics (8. 0.29) -
util.
debug. collectHighLoadDiagnostics (8. 0.31) -
util.
debug. collectSlowQueryDiagnostics (8. 0.31) -
※
() は機能が追加されたバージョン番号
これらのツールを使いこなすことで、システムの問題を早期に発見したり、さまざまな側面での原因調査が可能になります。なお、この記事ではMySQL Shell 8.
診断ユーティリティ
MySQL Shellにはバージョン8.
診断ユーティリティは取得したデータをtsv、yamlの2つのファイル形式で取得し、1つのアーカイブファイル
util.debug.collectDiagnostics
このユーティリティはサーバー全体の状態を一括で診断するためのツールです。を実行すると、以下のような情報を取得します。
- MySQLの構成情報
(PKのないテーブル一覧、設定されているシステム変数など) - MySQLのステータス情報
(稼働中のセッション、接続情報など) - レプリケーション関連情報
- エラーログ
- 主な用途
-
- サーバーの全体像を把握したいとき
- トラブル発生時に初期情報を収集したい場合
util.debug.collectHighLoadDiagnostics
このユーティリティはutil.
の内容に加えて、テーブルに関する追加の情報やスロークエリに関する情報などを追加で取得します。また、util.
は実行回数、実行間隔を指定することができます。デフォルトは、300秒間隔で2回実行します。
- 取得できる情報
-
- util.
debug. collectDiagnosticsで取得できる情報 - テーブルに関する情報
(サイズの大きいテーブル、テーブルの各種情報など) - sysスキーマから取得できるサマリ情報
- util.
- 主な用途
-
- 高負荷状態の原因となっている状態でさまざまな側面から調査を行いたい場合
util.debug.collectSlowQueryDiagnostics
スロークエリが特定できている状態で、その詳細な実行状況を調査するために使用されます。このユーティリティは、指定したクエリに対して実行計画やクエリを実行して、実際にかかった時間の情報などを取得することができます。
- 主な収集データ
-
- util.
debug. collectDiagnosticsの情報 - クエリに関する実行計画
- クエリに関連するテーブルの情報
- クエリ実行前後のメトリックス
- util.
- 主な用途
-
- 遅いクエリの最適化
- インデックスの見直しやクエリ修正の検討⠀
診断ユーティリティを利用してみる
実際に診断ユーティリティを利用してみましょう。診断ユーティリティを利用するには、MySQL Shellで対象のMySQLに接続する必要があります。ただ、接続するときに注意点があります。
- 接続する対象のMySQLのバージョンが5.
7以上であること - rootで実行すること
- スローログ関連の情報を取得する場合は
log_
であることoutput = TABLE
また、接続時先がlocalhostlocal_
)
実際にrootで接続して診断ユーティリティを実行してみます。
JS > util.debug.collectDiagnostics("diagnostics") Collecting diagnostics information from mysql://root@/tmp%2Fmysql.sock...
通常引数に指定したファイル名でカレントディレクトリに収集されます。
もし。引数にディレクトリ名/tmp/
)mysql-diagnostics-YYYYMMDD-HHMMSS.
という形式で生成されます。ここでの注意として、ディレクトリを指定する場合は最後の/
を忘れないようにしてください。たとえば引数に/tmp
を指定してしまった場合、/tmp/
配下ではなく/tmp.
というファイルが生成されてしまいます。
実際に実行してみると、以下のように取得している項目が確認できます。
JS > util.debug.collectDiagnostics("diagnostics") Collecting diagnostics information from mysql://root@/tmp%2Fmysql.sock... Copying shell log file... - Gathering schema tables without a PK... - Gathering schema routine size... - Gathering schema table count... - Gathering schema unused indexes... - Copying MySQL error log file (/data/mysql/error.log) - Gathering performance_schema.host_cache... - Gathering performance_schema.persisted_variables... - Gathering performance_schema.replication_applier_configuration... - Gathering performance_schema.replication_applier_filters... - Gathering performance_schema.replication_applier_global_filters... - Gathering performance_schema.replication_applier_status... - Gathering performance_schema.replication_applier_status_by_coordinator... - Gathering performance_schema.replication_applier_status_by_worker... - Gathering performance_schema.replication_asynchronous_connection_failover... - Gathering performance_schema.replication_asynchronous_connection_failover_managed... - Gathering performance_schema.replication_connection_configuration... - Gathering performance_schema.replication_connection_status... - Gathering performance_schema.replication_group_member_stats... - Gathering performance_schema.replication_group_members... - Gathering global variables... - Gathering XA RECOVER CONVERT xid... - Gathering SHOW BINARY LOGS... - Gathering SHOW REPLICAS... - Gathering SHOW BINARY LOG STATUS... - Gathering SHOW REPLICA STATUS... - Gathering replication master_info... - Gathering replication relay_log_info... - Gathering pfs actors... - Gathering pfs objects... - Gathering pfs consumers... - Gathering pfs instruments... - Gathering pfs threads... - Gathering performance_schema.metadata_locks... - Gathering performance_schema.threads... - Gathering sys.schema_table_lock_waits... - Gathering sys.session_ssl_status... - Gathering sys.session... - Gathering sys.processlist... - Gathering performance_schema.events_waits_current... - Gathering information_schema.innodb_trx... - Gathering information_schema.innodb_metrics... - Gathering sys.memory_by_host_by_current_bytes... - Gathering sys.memory_by_thread_by_current_bytes... - Gathering sys.memory_by_user_by_current_bytes... - Gathering sys.memory_global_by_current_bytes... - Gathering SHOW GLOBAL STATUS... - Gathering SHOW ENGINE INNODB STATUS... - Gathering SHOW ENGINE PERFORMANCE_SCHEMA STATUS... - Gathering SHOW FULL PROCESSLIST... - Gathering SHOW OPEN TABLES... Collecting system information for test-db01 (linux) -> Executing date -> Executing uname -a -> Executing getenforce -> Executing free -m -> Executing swapon -s -> Executing lsb_release -a -> Executing mount -v -> Executing df -h -> Executing cat /proc/cpuinfo -> Executing cat /proc/meminfo -> Executing cat /etc/fstab -> Executing mpstat -P ALL 1 4 -> Executing iostat -m -x 1 4 -> Executing vmstat 1 4 -> Executing top -b -n 4 -d 1 -> Executing ps aux -> Executing ulimit -a -> Executing for PID in `pidof mysqld`;do echo "# numastat -p $PID";numastat -p $PID;echo "# /proc/$PID/limits";cat /proc/$PID/limits;echo;done -> Executing dmesg -> Executing egrep -i 'err|fault|mysql' /var/log/* -> Executing pvs -> Executing pvdisplay -> Executing vgs -> Executing vgdisplay -> Executing lvs -> Executing lvdisplay -> Executing netstat -lnput -> Executing numactl --hardware -> Executing numastat -m -> Executing sysctl -a -> Executing dmidecode -s system-product-name -> Executing lsblk -i -> Executing sudo sosreport Diagnostics information was written to diagnostics.zip
出力量は多いですが、さまざまなクエリやコマンドを使って多様な情報が取得できていることが確認できます。出力されたdiagnostics.
試しにschema_
を見てみると、PKのないテーブル一覧がyaml形式で出力されていることがわかります。
$ cat schema_tables_without_a_PK.yaml # Query: # SELECT t.table_schema, t.table_name, t.table_rows, t.engine, t.data_length, t.index_length # FROM information_schema.tables t # LEFT JOIN information_schema.statistics s on t.table_schema=s.table_schema and t.table_name=s.table_name and s.index_name='PRIMARY' # WHERE s.index_name is NULL and t.table_type = 'BASE TABLE' # and t.table_schema not in ('performance_schema', 'sys', 'mysql', 'information_schema') # # Started: 2024-11-20T00:19:13.303793 # Execution Time: 0.0114 sec # DATA_LENGTH: 16384 ENGINE: InnoDB INDEX_LENGTH: 0 TABLE_NAME: user TABLE_ROWS: 4 TABLE_SCHEMA: test --- DATA_LENGTH: 16384 ENGINE: InnoDB INDEX_LENGTH: 0 TABLE_NAME: t10 TABLE_ROWS: 0 TABLE_SCHEMA: d1 ...
便利なオプション
診断ユーティリティにはそれぞれ便利なオプションがあるので、いくつか紹介します。
util.debug.collectHighLoadDiagnostics
- allMembers
(defautl: false) - trueの場合にInnoDB Clusterの管理対象トポロジの情報も取得します。
- schemaStats
(defautl: false) - trueの場合に
schema_
object_ overview (viewの一覧) と top_
を追加で取得します。biggest_ tables - slowQueries
(defautl: false) - trueの場合にスロークエリの情報(
mysql.
)を収集します。ただし、スロークエリの出力先がTABLEである必要があります。slow_ log - ignoreErrors
(defautl: false) - trueの場合に収集に利用されるクエリがエラーの場合でも無視されます。
- customSql/
customShell - 収集時に指定したSQL、Shellを実行することができます。以下はcustomSqlを1つ指定する例です。収集が完了すると、
0.
というファイルに実行結果が出力されます。custom_ sql-script_ 0. tsv
JS> util.debug.collectDiagnostics("/tmp/", {"customSql": ["{ここにSQLを追加する}"]})
util.debug.collectHighLoadDiagnostics
- iterations
- 指定した回数実行します。
- delay
- 指定した秒数分実行間隔を空けます。
まとめ
今回は、MySQL Shellの診断ユーティリティの機能について紹介しました。今回取り上げたオプション以外にも、パフォーマンスに影響を与えるものの、SHOW ENGINE INNODB MUTEXを用いてInnoDBのミューテックス情報を取得することも可能です。
デフォルト設定でも多くの情報を収集できますが、customSqlやcustomShellオプションを設定することで、さらに詳細な情報を取得することができます。これらの診断ユーティリティは、頻繁に実行して定点観測を行うよりも、問題が発生した際に迅速に情報を収集し、その後の分析に役立てる運用が適していると言えるでしょう。
より深い理解を得るために、診断ユーティリティの詳細については、公式ドキュメント Diagnostics Utilitiesを参照してご利用ください。