概要
クエリビルダやORMが生成するクエリを確認したいなどの理由で、MySQLに投げられたクエリを確認したくなることがある
そういうときは、MySQLのクエリログ (general_log) と言う設定をONにすることによって、すべてのクエリをログに吐かせることができる
5.2.3 一般クエリーログ 一般クエリーログは、mysqld の実行内容の一般的な記録です。サーバーは、クライアントが接続または接続解除したときに情報をこのログに書き込み、クライアントから受け取った各 SQL ステートメントをログに記録します。一般クエリーログは、クライアント側でエラーが疑われるとき、クライアントが mysqld に送信した内容を正確に知りたい場合に非常に役立つことがあります。
やってみる
1. 現在の設定を確認する
mysql> select version(); +-----------+ | version() | +-----------+ | 8.0.16 | +-----------+ 1 row in set (0.00 sec) mysql> show variables like 'general_log%'; +------------------+---------------------------------+ | Variable_name | Value | +------------------+---------------------------------+ | general_log | OFF | | general_log_file | /var/lib/mysql/3a9a8fa16e7a.log | +------------------+---------------------------------+ 2 rows in set (0.00 sec)
デフォルトではOFFになっている。この状態で クエリが投げられてもロギングされない
root@3a9a8fa16e7a:/# ls -alh /var/lib/mysql/3a9a8fa16e7a.log ls: cannot access '/var/lib/mysql/3a9a8fa16e7a.log': No such file or directory
2. ONにしてみる
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> set global general_log = on; Query OK, 0 rows affected (0.02 sec) mysql> show variables like 'general_log%'; +------------------+---------------------------------+ | Variable_name | Value | +------------------+---------------------------------+ | general_log | ON | | general_log_file | /var/lib/mysql/3a9a8fa16e7a.log | +------------------+---------------------------------+ 2 rows in set (0.01 sec)
クエリログの設定をONにしたところ即座にログファイルが作られた
root@3a9a8fa16e7a:/# ls -alh /var/lib/mysql/3a9a8fa16e7a.log -rw-r----- 1 root root 256 5月 25 17:17 /var/lib/mysql/3a9a8fa16e7a.log
3. ロギングされるか確かめる
適当にクエリを投げてみる
mysql> select 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.01 sec)
root@3a9a8fa16e7a:/# tail /var/lib/mysql/3a9a8fa16e7a.log /usr/sbin/mysqld, Version: 8.0.16 (MySQL Community Server - GPL). started with: Tcp port: 3306 Unix socket: /var/run/mysqld/mysqld.sock Time Id Command Argument 2019-05-25T08:17:19.278525Z 26 Query show variables like 'general_log%' 2019-05-25T08:18:11.802232Z 25 Query select 1
投げたクエリはちゃんとログファイルに書かれていた🎉
補足 (1)
本番環境でクエリログを取る場合、下記に注意すること
- ログのぶんだけディスクを食うし、ディスクI/Oが増えるぶんパフォーマンスも劣化する
- 機微情報を扱うクエリが投げられる場合、ログにも機微情報が乗るのでログファイルは慎重に扱う
補足 (2)
デフォルトではgeneral logはファイルに吐き出されるが、 log_output
という変数を変更することで吐き出し先をテーブルに変更することもできる
mysql> set global log_output = "table";