一方で、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でローテーション必須
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
general_logとスロークエリログの違い
MySQLには目的の異なる2種類のクエリログがあります。混同しやすいので先に整理します。| ログ種類 | 記録対象 | 主な用途 |
|---|---|---|
| general_log(一般クエリログ) | 全ての接続・切断・クエリ(実行速度に関係なく) | デバッグ・全SQL可視化・一時的な調査 |
| slow_query_log(スロークエリログ) | long_query_time秒を超えたクエリのみ | パフォーマンス改善・本番での遅いSQL特定 |
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_logがOFF、出力ファイルは/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
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 | +----------------------------+----------------------+--------------+-------------------------------------+
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;
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
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]セクション) |
Linux Master Pro Seminar の詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:MySQLのデッドロックを調査する手順|SHOW ENGINE INNODB STATUSで原因を特定してロック競合を解消する
- この記事の属するカテゴリ:データーベース管理へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます