0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Docker+MySQL】General Logを設定してクエリをリアルタイム監視する完全ガイド

0
Posted at

【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}'

トラブルシューティング

ログファイルが作成されない場合

  1. MySQLコンテナが正常に起動しているか確認
  2. 設定ファイルのパーミッションを確認
  3. 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やストックをよろしくお願いします!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?