MySQL默认关闭general_log,需SUPER权限且确保服务端允许写日志;临时开启用SET GLOBAL general_log = ON,路径由@@general_log_file决定,修改路径必须在my.cnf中配置并重启。

general_log 开关和日志路径怎么设
MySQL 默认关闭 general_log,打开前得确认你有 SUPER 权限,且服务端允许写日志文件(比如 SELinux 或 Docker 容器里可能被拦截)。
实操建议:
- 先查当前状态:
SELECT @@general_log, @@general_log_file; - 临时开启(重启失效):
SET GLOBAL general_log = ON;,日志默认写到hostname.log,路径由@@general_log_file决定,一般在 MySQL 数据目录下 - 想改路径?必须在配置文件
my.cnf里加:[mysqld]<br>general_log = ON<br>general_log_file = /var/log/mysql/general.log
,然后重启 mysqld —— 动态 SET 是不能改路径的 - 注意:日志文件需 MySQL 进程有写权限,否则
general_log会静默失败(SHOW VARIABLES LIKE 'general_log%'看值是 ON,但文件没生成)
日志内容里哪些字段真正有用
general_log 每行一条记录,格式固定:时间、线程ID、命令类型、参数。不是所有字段都值得盯,重点看这三块:
-
Command列:值为Query才是真实执行的 SQL;Connect/Quit/Prepare这些可以忽略 -
Argument列:就是原始 SQL,但注意它不包含注释、换行会被压缩成空格,长语句可能被截断(取决于max_allowed_packet) - 时间戳是服务器本地时间,没毫秒精度,不适合做精确耗时分析 —— 想看执行时间得用
slow_query_log或 Performance Schema
线上环境能不能直接开 general_log
不能,除非你明确接受性能下跌和磁盘爆炸风险。
原因很实在:
- 每条客户端请求(哪怕只是 ping)都落盘,QPS 上千时日志写入 I/O 压力巨大,可能拖慢整个实例
- 日志文件无自动轮转,
FLUSH LOGS可手动切,但没人盯的话几天就能占满磁盘 - 敏感信息全明文记录:密码如果写在 SQL 里(比如
SET PASSWORD)、业务 ID、手机号都会进日志 —— 审计和合规上容易出事 - 替代方案更稳妥:用
performance_schema.events_statements_history_long查最近执行过的 SQL(内存中,不落盘),或者抓包 +tcpdump port 3306配合pt-query-digest
查完怎么快速过滤出目标 SQL
日志是纯文本,别用肉眼扫。直接上命令行工具链最省事:
- 找某个库的操作:
grep 'database_name' /var/log/mysql/general.log | grep 'Query' - 排除系统账号干扰(比如监控脚本):
grep 'Query' /var/log/mysql/general.log | grep -v 'monitor_user\|health_check' - 想看某张表被谁查过:
awk '/Query/ && /UPDATE.*orders|SELECT.*orders/ {print $0}' /var/log/mysql/general.log - 注意:日志里表名不带反引号,大小写取决于
lower_case_table_names设置,匹配时别硬套 `orders` 这种写法</li> </ul> <p>日志文件一旦大了(比如超 500MB),<code>grep
会卡,优先用tail -n 10000截最新部分再筛,别直接全文扫。


















