【Docker+MySQL】General Logを設定してクエリをリアルタイム監視する完全ガイド
Docker環境でMySQLを使用する際、実行されたクエリを確認したい場合があります。特に開発環境ではデバッグやパフォーマンス分析のためにgeneral logが非常に便利です。
この記事では、Docker Composeを使用してMySQLコンテナを起動し、general logを有効にしてクエリログを確認する方法を、実践的なノウハウとともに紹介します。
この記事で学べること
- ✅ Docker ComposeでMySQLのgeneral logを設定する方法
- ✅ リアルタイムでクエリログを監視するテクニック
- ✅ 本番環境と開発環境で設定を切り替える方法
- ✅ パフォーマンス影響を理解し、安全に運用する知識
- ✅ トラブルシューティングとベストプラクティス
対象読者
- DockerでMySQL環境を構築している開発者
- アプリケーションのデバッグでSQLクエリを確認したい方
- データベースのパフォーマンス分析をしたい方
動作確認環境
- Docker: 24.0+
- Docker Compose: 2.0+
- MySQL: 8.0
概要
-
general_log=1でgeneral logを有効化 -
log_output=FILEでファイルに出力 -
general_log_fileでログファイルの場所を指定 -
docker compose execでログをリアルタイム確認
Docker Compose設定
まず、docker-compose.ymlファイルを作成します:
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql_general_log
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: testdb
MYSQL_USER: testuser
MYSQL_PASSWORD: testpass
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
restart: unless-stopped
volumes:
mysql_data:
MySQL設定ファイル
mysql/conf.d/my.cnfファイルを作成してgeneral logの設定を追加します:
[mysqld]
# General Log設定
general_log = 1
log_output = FILE
general_log_file = /var/lib/mysql/general.log
# その他便利な設定
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 1
ディレクトリ構成
project/
├── docker-compose.yml
└── mysql/
└── conf.d/
└── my.cnf
起動と確認
1. コンテナを起動
docker compose up -d
2. MySQLに接続してテストクエリを実行
# コンテナ内のMySQLに接続
docker compose exec mysql mysql -u root -p
# パスワードを入力後、テストクエリを実行
USE testdb;
SELECT * FROM mysql.user;
SHOW DATABASES;
3. General Logをリアルタイムで確認
# ログをリアルタイムで表示
docker compose exec mysql tail -f /var/lib/mysql/general.log
ログ出力例
general logには以下のような形式でクエリが出力されます:
2024-03-26T06:00:00.123456Z 5 Query SELECT * FROM mysql.user
2024-03-26T06:00:01.234567Z 5 Query SHOW DATABASES
2024-03-26T06:00:02.345678Z 5 Query USE testdb
実用的なTips
ログのローテーション
注意: MySQLのgeneral logは自動ローテーションをサポートしていません。手動での対応が必要です。
方法1: シェルスクリプトでのローテーション
#!/bin/bash
# log_rotation.sh
CONTAINER_NAME="mysql_general_log"
LOG_FILE="/var/lib/mysql/general.log"
MAX_SIZE="100M" # 100MBを超えたらローテーション
# コンテナ内のログファイルサイズを確認
SIZE=$(docker compose exec mysql sh -c "du -sh $LOG_FILE | cut -f1")
if [[ $SIZE == *"M"* ]]; then
NUM_SIZE=$(echo $SIZE | sed 's/M//')
if (( $(echo "$NUM_SIZE > 100" | bc -l) )); then
echo "Log file size is $SIZE, rotating..."
# ログをリネーム
docker compose exec mysql sh -c "mv $LOG_FILE ${LOG_FILE}.$(date +%Y%m%d_%H%M%S)"
# MySQLにログの再作成を指示(FLUSH LOGS)
docker compose exec mysql mysql -u root -p -e "FLUSH LOGS;"
echo "Log rotation completed"
fi
fi
方法2: logrotateを使用
# /etc/logrotate.d/mysql_general_log
/var/lib/mysql/general.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 660 mysql mysql
postrotate
docker compose exec mysql mysql -u root -p -e "FLUSH LOGS;"
endscript
}
開発環境限定の設定
重要: 本番環境ではパフォーマンスに重大な影響があるため、general logは必ず無効化してください。
方法1: 環境変数で制御する高度な設定
# docker-compose.yml
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: testdb
MYSQL_USER: testuser
MYSQL_PASSWORD: testpass
# 環境変数でlog設定を制御
- ENABLE_GENERAL_LOG=${ENABLE_GENERAL_LOG:-0}
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
- ./mysql/conf.d:/etc/mysql/conf.d
command: >
--general_log=${ENABLE_GENERAL_LOG:-0}
--log_output=FILE
--general_log_file=/var/lib/mysql/general.log
方法2: 設定ファイルを環境で切り替え
# 開発環境
ENABLE_GENERAL_LOG=1 docker compose up -d
# 本番環境
ENABLE_GENERAL_LOG=0 docker compose up -d
# mysql/conf.d/development.cnf
[mysqld]
general_log = 1
log_output = FILE
general_log_file = /var/lib/mysql/general.log
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 1
# mysql/conf.d/production.cnf
[mysqld]
general_log = 0
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 2
パフォーマンス影響と注意点
General Logのパフォーマンス影響
- CPU使用率: 5-15%の増加(クエリ量による)
- ディスクI/O: 全クエリが書き込まれるため増加
- ストレージ: 時間と共にログファイルが肥大化
安全な運用のためのベストプラクティス
[mysqld]
# 開発環境での推奨設定
general_log = 1
log_output = FILE
general_log_file = /var/lib/mysql/general.log
# ログファイルのサイズ制限(手動ローテーション用)
# MySQL 8.0ではlog_timestampsでタイムゾーンを指定
log_timestamps = SYSTEM
# ログローテーションスクリプト例
docker compose exec mysql sh -c '
mv /var/lib/mysql/general.log /var/lib/mysql/general.log.$(date +%Y%m%d_%H%M%S)
kill -USR1 $(cat /var/run/mysqld/mysqld.pid)
'
ログのフィルタリングと分析
基本的なフィルタリング
# 特定のユーザーのクエリを監視
docker compose exec mysql tail -f /var/lib/mysql/general.log | grep "testuser"
# 特定のテーブルへのクエリを監視
docker compose exec mysql tail -f /var/lib/mysql/general.log | grep "users"
# ERRORのみを監視
docker compose exec mysql tail -f /var/lib/mysql/general.log | grep -i error
# SELECTクエリのみを監視
docker compose exec mysql tail -f /var/lib/mysql/general.log | grep "Query SELECT"
高度なログ分析
# クエリ実行回数をカウント
docker compose exec mysql sh -c 'cat /var/lib/mysql/general.log | grep "Query" | cut -d" " -f6- | sort | uniq -c | sort -nr'
# 特定時間帯のログを抽出
docker compose exec mysql sh -c 'grep "2024-03-26T10:" /var/lib/mysql/general.log'
# リアルタイムでクエリ実行時間を監視
docker compose exec mysql tail -f /var/lib/mysql/general.log | awk '{print $1, $6, $7, $8, $9, $10}'
トラブルシューティング
ログファイルが作成されない場合
- MySQLコンテナが正常に起動しているか確認
- 設定ファイルのパーミッションを確認
-
my.cnfの構文を確認
# コンテナのステータス確認
docker compose ps
# 設定ファイルの確認
docker compose exec mysql cat /etc/mysql/conf.d/my.cnf
# MySQL変数の確認
docker compose exec mysql mysql -u root -p -e "SHOW VARIABLES LIKE 'general_log%';"
ログが出力されない場合
-- MySQL内で設定を確認
SHOW VARIABLES LIKE 'general_log';
SHOW VARIABLES LIKE 'log_output';
SHOW VARIABLES LIKE 'general_log_file';
-- 設定を動的に変更(一時的)
SET GLOBAL general_log = 'ON';
まとめ
Docker上でMySQLのgeneral logを設定することで、簡単にクエリの実行状況を監視できます。特に開発環境でのデバッグやパフォーマンス分析に非常に役立ちます。
主要なポイント
- ✅ 設定は簡単:
my.cnfに3行追加するだけ - ✅ リアルタイム監視:
tail -fコマンドで簡単に確認 - ✅ 柔軟な運用: 環境変数で本番/開発を切り替え可能
- ✅ 安全な運用: パフォーマンス影響を理解し、適切に管理
注意事項
- ⚠️ 本番環境での使用は慎重に: パフォーマンスに重大な影響
- ⚠️ ログの肥大化: 適切なローテーション設定が必要
- ⚠️ セキュリティ: 機密情報がログに含まれる可能性
次のステップ
- この設定をプロジェクトの開発環境に導入
- チームでログ分析の方法を標準化
- 監視ツールとの連携を検討
ぜひプロジェクトの開発環境に取り入れて、効率的なデバッグとパフォーマンス分析を実現してください!
参考リンク
この記事が役に立ったら、LGTMやストックをよろしくお願いします!