いろは2986023 views
MathPython491378 views
英語607877 views
ヒストリア284143 views
高校国語785655 views
小学理科717236 views
高校生物549842 views
高校化学2913383 views
小学社会308636 views
教育148875 views
Help
Tools

English

MySQL のログ管理 - スロークエリログ・エラーログ・一般ログの活用

MySQL が出力するログは、障害対応やパフォーマンス改善の最も重要な手がかりになります。ログの種類と特性を理解し、適切に設定・管理することが安定運用の鍵です。

MySQL のログ体系

MySQL には複数のログが用意されており、それぞれ異なる目的で使われます。すべてを有効にすれば良いというわけではなく、用途とディスク容量のバランスを考えた設定が求められます。

ログ種別主な用途デフォルト
エラーログ起動失敗・クラッシュの診断有効
スロークエリログ遅いクエリの特定無効
一般クエリログ全クエリの記録無効

エラーログだけがデフォルトで有効になっており、他のログは明示的に有効化する必要があります。

エラーログ

エラーログは MySQL が起動・停止した記録や、実行中に発生した深刻なエラーを記録するものです。障害時に最初に確認すべきログであり、常に有効にしておくべきものになります。

-- エラーログの場所を確認
SHOW VARIABLES LIKE 'log_error';

-- エラーログの詳細度を確認
SHOW VARIABLES LIKE 'log_error_verbosity';

log_error_verbosity の設定値によって、記録される情報の詳細度が変わります。

1(エラーのみ)

2(エラー + 警告)

3(エラー + 警告 + 情報)

本番環境では 2 に設定するのが一般的です。3 にすると情報量が増えすぎてログファイルが肥大化するため、問題の調査時に一時的に上げるという運用が適しています。

設定ファイル(my.cnf)での指定は以下のようになります。

[mysqld]
log_error = /var/log/mysql/error.log
log_error_verbosity = 2

スロークエリログ

スロークエリログは、実行に一定時間以上かかったクエリを記録するログです。パフォーマンスチューニングにおいて最も活用頻度が高く、有効化しておくことを強く推奨します。

-- スロークエリログを有効化
SET GLOBAL slow_query_log = ON;

-- 閾値を 1 秒に設定
SET GLOBAL long_query_time = 1;

-- インデックス未使用のクエリも記録
SET GLOBAL log_queries_not_using_indexes = ON;

long_query_time はデフォルトで 10 秒に設定されていますが、これでは多くの問題クエリを見逃してしまいます。本番環境では 1 秒以下に設定するのが実用的です。

long_query_time = 10(デフォルト)

極端に遅いクエリしか記録されず、日常的なパフォーマンス劣化を検知できない。

long_query_time = 1(推奨)

ユーザー体感に影響するレベルのクエリを幅広く記録でき、改善の手がかりが増える。

設定ファイルで永続化する場合は以下のように記述します。

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1

スロークエリログの分析

記録されたスロークエリログは、MySQL に付属する mysqldumpslow コマンドで集計・分析できます。

# 実行回数が多い順にトップ 10 を表示
mysqldumpslow -s c -t 10 /var/log/mysql/slow.log

# 平均実行時間が長い順にトップ 10 を表示
mysqldumpslow -s at -t 10 /var/log/mysql/slow.log

mysqldumpslow は類似クエリをまとめて集計してくれるため、パラメータが異なるだけの同一パターンのクエリを一括で把握できます。さらに詳細な分析が必要な場合は、Percona Toolkit の pt-query-digest が有力な選択肢となります。

# pt-query-digest による詳細分析
pt-query-digest /var/log/mysql/slow.log > slow_report.txt

pt-query-digest はクエリごとの実行回数・合計時間・平均時間・95 パーセンタイルなどを算出し、改善すべきクエリの優先順位付けに役立ちます。

一般クエリログ

一般クエリログは MySQL に送信されたすべてのクエリを記録するログです。デバッグや監査目的で使われますが、すべてのクエリを記録するためディスク I/O への負荷が大きく、本番環境で常時有効にするのは推奨されません。

-- 一般クエリログの有効化(一時的な調査用)
SET GLOBAL general_log = ON;
SET GLOBAL general_log_file = '/var/log/mysql/general.log';

-- 調査終了後に無効化
SET GLOBAL general_log = OFF;

一般クエリログの典型的な利用シーンとしては、アプリケーションが発行しているクエリの全体像を把握したい場合や、意図しないクエリが実行されていないかを監査する場面が挙げられます。

デバッグ利用

アプリケーションのバグ調査時に一時的に有効化し、実際に発行されているクエリを確認する。ORM が生成するクエリの検証にも有効。

セキュリティ監査

不正なアクセスや意図しないデータ操作がないかを確認する目的で、短期間だけ有効化して監査を行う。

ログのローテーション

ログファイルは放置すると際限なく肥大化します。定期的なローテーションの仕組みを整備しておくことが不可欠です。

MySQL のログローテーションには、OS の logrotate を利用するのが一般的な方法です。

# /etc/logrotate.d/mysql
/var/log/mysql/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 640 mysql adm
    postrotate
        /usr/bin/mysqladmin flush-logs
    endscript
}

postrotatemysqladmin flush-logs を実行することにより、MySQL が新しいログファイルに書き込みを切り替えます。この設定を忘れると、ローテーション後も古いファイルディスクリプタに書き込み続けてしまい、ログが正しく分割されません。

バイナリログとの関係

運用管理の文脈では、バイナリログ(binlog)も重要な存在です。バイナリログはデータの変更操作を記録するもので、レプリケーションやポイントインタイムリカバリに使われます。

-- バイナリログの状態確認
SHOW VARIABLES LIKE 'log_bin';

-- バイナリログの一覧表示
SHOW BINARY LOGS;

-- 古いバイナリログの削除
PURGE BINARY LOGS BEFORE '2025-01-01 00:00:00';

バイナリログは自動的に削除されないため、ディスク容量の逼迫を防ぐには binlog_expire_logs_seconds(MySQL 8.0 以降)を設定しておく必要があります。

[mysqld]
binlog_expire_logs_seconds = 604800  # 7日間保持

ログ管理のベストプラクティス

ログの設定は「とりあえず全部有効にする」のではなく、目的に応じた取捨選択が重要です。エラーログは常時有効、スロークエリログも常時有効が基本であり、一般クエリログは必要なときだけ有効にするのが現実的な運用方針になります。

エラーログ常時有効(必須)
スロークエリログ常時有効(推奨)
一般クエリログ調査時のみ有効
バイナリログレプリケーション・リカバリ用途で有効

ログの保存期間やローテーション設定を放置すると、ディスク容量不足で MySQL 自体が停止する事態にもなりかねません。運用開始時にログ管理のルールを策定し、監視体制と組み合わせて運用してください。