MySQLの一般クエリログ(general_log)を有効化して全SQLを記録する方法|設定手順と運用上の注意点

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtipsデーターベース管理 > MySQLの一般クエリログ(general_log)を有効化して全SQLを記録する方法|設定手順と運用上の注意点
MySQLで「どのプロセスがいつ、どんなSQLを発行したか」を調べたい場面があります。スロークエリログは指定時間を超えたクエリしか記録しないため、速いクエリを含めて全件記録したい場合や、開発環境でアプリが発行するSQLを可視化したい場合には、一般クエリログ(general_log)が役立ちます。

一方で、general_logは全クエリを記録するためディスクへの書き込みが大量に発生します。本番の高負荷DBサーバーで常時ONにするとI/Oがボトルネックになることがあるため、調査目的での一時的な利用が推奨です。

この記事では、RHEL 9.4 / Ubuntu 24.04 LTS上のMySQL 8.4を例に、general_logの有効化・ファイル出力とテーブル出力の切り替え・本番で負荷をかけずに使う手順・ログローテーションの設定まで、実機出力付きで解説します。

この記事のポイント

・SET GLOBAL general_log = ONで即時有効化・OFFで即時無効化できる
・出力先はファイルとテーブル(mysql.general_log)の2択で切り替え可能
・本番DBでは短時間だけグローバルONにし、調査後すぐOFFに戻すのが安全
・常時ONにする場合はlogrotateとFLUSH GENERAL LOGSでローテーション必須


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

general_logとスロークエリログの違い

MySQLには目的の異なる2種類のクエリログがあります。混同しやすいので先に整理します。
ログ種類 記録対象 主な用途
general_log(一般クエリログ) 全ての接続・切断・クエリ(実行速度に関係なく) デバッグ・全SQL可視化・一時的な調査
slow_query_log(スロークエリログ) long_query_time秒を超えたクエリのみ パフォーマンス改善・本番での遅いSQL特定
スロークエリログは本番で常時有効にして、general_logは必要な時に限定して使うのが基本の運用スタイルです。

general_logの現在の設定を確認する

1. グローバル変数を確認する

MySQLに接続して以下のSQLを実行します。

mysql> SHOW GLOBAL VARIABLES LIKE 'general%'; +------------------+----------------------------+ | Variable_name | Value | +------------------+----------------------------+ | general_log | OFF | | general_log_file | /var/lib/mysql/db01.log | +------------------+----------------------------+

general_logOFF、出力ファイルは/var/lib/mysql/db01.log(ホスト名.log)がデフォルト値です。

2. 出力先の設定を確認する

mysql> SHOW GLOBAL VARIABLES LIKE 'log_output'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_output | FILE | +---------------+-------+

log_outputはファイル出力(FILE)・テーブル出力(TABLE)・両方(FILE,TABLE)から選択できます。

general_logをグローバルに有効化する

1. SET GLOBALで動的に有効化する(再起動不要)

# 有効化(SUPER または SYSTEM_VARIABLES_ADMIN 権限が必要) mysql> SET GLOBAL general_log = ON; Query OK, 0 rows affected (0.01 sec) # 確認 mysql> SHOW GLOBAL VARIABLES LIKE 'general_log'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | general_log | ON | +---------------+-------+

2. ログ出力をリアルタイムで確認する

# tail でリアルタイム確認 # tail -f /var/lib/mysql/db01.log /usr/sbin/mysqld, Version: 8.4.0 MySQL Community Server - GPL. started with: Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock Time Id Command Argument 2026-09-19T04:22:31.412834Z 11 Connect appuser@localhost on production using Socket 2026-09-19T04:22:31.413104Z 11 Query SELECT id FROM orders WHERE status = 'pending' 2026-09-19T04:22:31.414821Z 11 Query UPDATE orders SET status = 'done' WHERE id = 4821 2026-09-19T04:22:31.416003Z 11 Quit

時刻・スレッドID・コマンド種別(Connect / Query / Quit)・SQLが順に記録されます。

3. my.cnfに設定を永続化する

SET GLOBALはMySQLを再起動するとリセットされます。再起動後も有効にするにはmy.cnfに追記します。

# /etc/my.cnf(RHEL系)または /etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu系) [mysqld] general_log = ON general_log_file = /var/log/mysql/general.log

デフォルトの/var/lib/mysql/ではなく/var/log/mysql/に出力先を変更しておくと、logrotateとの連携が容易です。

ログの出力先をテーブルに変更する

1. テーブル出力に切り替える

mysql> SET GLOBAL log_output = 'TABLE'; Query OK, 0 rows affected (0.00 sec) mysql> SET GLOBAL general_log = ON; Query OK, 0 rows affected (0.00 sec)

2. mysql.general_logテーブルを確認する

mysql> SELECT event_time, user_host, command_type, LEFT(argument, 60) AS sql_abbr FROM mysql.general_log ORDER BY event_time DESC LIMIT 5; +----------------------------+----------------------+--------------+-------------------------------------+ | event_time | user_host | command_type | sql_abbr | +----------------------------+----------------------+--------------+-------------------------------------+ | 2026-09-19 04:30:01.987654 | appuser[appuser]@localhost | Query | SELECT id FROM products LIMIT 10 | | 2026-09-19 04:30:00.111222 | appuser[appuser]@localhost | Connect| | | 2026-09-19 04:29:58.654321 | root[root]@localhost | Query | SET GLOBAL log_output = TABLE | +----------------------------+----------------------+--------------+-------------------------------------+

テーブル出力の利点はSQLで絞り込み検索が容易な点です。特定ユーザーのクエリだけを抽出したい場合にすぐWHERE user_host LIKE 'appuser%'で絞り込めます。

3. テーブルのデータをクリアする

# general_logを一時停止してからTRUNCATEする mysql> SET GLOBAL general_log = OFF; mysql> TRUNCATE TABLE mysql.general_log; mysql> SET GLOBAL general_log = ON;

MySQLのログ設定を含む実践的なLinuxサーバー運用スキルを体系的に習得したい方へ。20年以上の現場経験を持つ講師がハンズオンで指導するセミナーを開催しています。
Linux Master Pro Seminar の詳細を見る >>

本番DBで負荷をかけずにgeneral_logを使う

本番の高トラフィックなDBでgeneral_logを常時ONにすると、全クエリのディスク書き込みが追加されるためI/O負荷が増加します。調査目的での一時利用には以下の手順が安全です。

1. 短時間だけグローバルONにして調査する

# ステップ1: ファイル出力で有効化する mysql> SET GLOBAL log_output = 'FILE'; mysql> SET GLOBAL general_log = ON; # ステップ2: 別端末でアプリの操作やSQLを実行する(調査対象の操作) # ステップ3: 調査が終わったらすぐにOFFにする mysql> SET GLOBAL general_log = OFF; # ステップ4: ログで対象ユーザーのクエリを確認する # grep 'appuser' /var/lib/mysql/db01.log | grep 'Query'

2. sql_log_offでDBA自身のクエリを除外する

グローバルでgeneral_logをONにした状態で、自分のDBAセッションのクエリをログから除外したい場合はsql_log_offを使います。

# DBAセッション: 自分のクエリはgeneral_logに記録しない mysql> SET SESSION sql_log_off = ON; # 確認(このSELECT自体はログに残らない) mysql> SHOW SESSION VARIABLES LIKE 'sql_log_off'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sql_log_off | ON | +---------------+-------+ # 元に戻す場合 mysql> SET SESSION sql_log_off = OFF;

sql_log_off = ONにしたセッションのクエリはgeneral_logに書き込まれません。アプリユーザーのセッションにはこの設定を入れていないため、そのセッションのクエリだけが記録されます。

general_logファイルをlogrotateで管理する

general_logをファイル出力で常時有効にする場合、定期的なローテーションが必要です。単純にファイルを削除・移動してもMySQLがファイルハンドルを握り続けるため、FLUSH GENERAL LOGSコマンドで新しいファイルハンドルを開かせる必要があります。

1. logrotate設定ファイルを作成する

# /etc/logrotate.d/mysql-general-log として保存する /var/log/mysql/general.log { daily rotate 7 compress missingok notifempty postrotate mysql --defaults-file=/root/.my.cnf -e "FLUSH GENERAL LOGS;" 2>/dev/null endscript }

/root/.my.cnfにMySQLのroot認証情報を記載しておくと、スクリプト内にパスワードを直書きしなくて済みます。

# /root/.my.cnf の記載例 [client] user = root password = 設定したrootパスワード

2. logrotateの設定をテストする

# ドライラン(実際にはローテーションしない) # logrotate -d /etc/logrotate.d/mysql-general-log reading config file /etc/logrotate.d/mysql-general-log Handling 1 logs rotating pattern: /var/log/mysql/general.log after 1 days (7 rotations) empty log files are not rotated, old logs are removed

トラブルシュート——よくある問題と対処

「ディスクが短時間で満杯になる」場合

高トラフィックなDBでgeneral_logを常時ONにすると、数時間でGBオーダーのログが溜まります。

対処法:
・general_logは調査が終わったらすぐOFFにする
・本番での常時利用を避け、スロークエリログで代替できるか検討する
・テーブル出力を使い、定期的にTRUNCATEで古いデータを削除する

「MySQLを再起動したらgeneral_logがOFFに戻った」場合

SET GLOBALによる変更は一時的です。再起動後も有効にするには、my.cnfの[mysqld]セクションにgeneral_log = ONを追記してください。

「Access denied」でSET GLOBALが実行できない場合

mysql> SET GLOBAL general_log = ON; ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation

SET GLOBALにはSUPERまたはSYSTEM_VARIABLES_ADMIN権限が必要です。mysql -u rootで再ログインするか、操作ユーザーに必要な権限を付与してください。

「general_log_fileに書き込めない」場合

# /var/log/mysql/ ディレクトリの所有者を確認する # ls -la /var/log/ | grep mysql drwxr-x--- 2 mysql mysql 4096 Sep 19 05:00 mysql # MySQLプロセスの実行ユーザーを確認する # ps aux | grep mysqld | grep -v grep mysql 1234 5.2 12.4 3891520 506892 ? Ssl 04:00 2:14 /usr/sbin/mysqld

ディレクトリの所有者がmysqlユーザーになっていれば書き込み可能です。別のユーザーになっている場合はchown mysql:mysql /var/log/mysql/で修正してください。

本記事のまとめ

やりたいこと コマンド・設定
general_logの状態を確認する SHOW GLOBAL VARIABLES LIKE 'general%'
general_logを動的に有効化する SET GLOBAL general_log = ON
general_logを動的に無効化する SET GLOBAL general_log = OFF
出力先をテーブルに変更する SET GLOBAL log_output = 'TABLE'
テーブルのログを閲覧する SELECT * FROM mysql.general_log ORDER BY event_time DESC
テーブルのログを削除する TRUNCATE TABLE mysql.general_log
自セッションのログを除外する SET SESSION sql_log_off = ON
ログファイルをローテーションする FLUSH GENERAL LOGS
my.cnfで永続化する general_log = ON([mysqld]セクション)
MySQLのgeneral_logは「全クエリを記録する」という強力な機能ですが、本番環境での常時利用はディスクI/Oの増加というリスクが伴います。開発・テスト環境での全SQL可視化や、本番での短時間の一時調査に限定して活用するのが現場での基本スタンスです。ファイル出力で常時有効にする場合は、logrotateとFLUSH GENERAL LOGSを組み合わせたローテーション設計を事前に整えておいてください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、MySQLを含むLinuxサーバー運用を20年以上の現場経験を持つ講師が実機ハンズオンで指導します。
Linux Master Pro Seminar の詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。