通用查询日志(general_log)默认关闭,开启需谨慎:查SHOW VARIABLES LIKE 'general_log%'确认状态,临时启用用SET GLOBAL general_log = ON,永久配置需修改my.cnf并重启;输出可选FILE或TABLE,但TABLE易引发锁争用且8.0+默认禁用;日志含敏感信息,须评估性能与磁盘压力,及时关闭。

通用查询日志(general_log)能记录所有到达 MySQL 的 SQL 语句(含 SELECT、连接/断开等),但默认关闭,且生产环境长期开启会明显拖慢性能。必须按需启用、及时关闭、注意权限和路径写入权限。
如何确认 general_log 当前是否开启
直接查变量比猜更可靠:SHOW VARIABLES LIKE 'general_log%';。重点看两行:
-
general_log值为ON才算开启;OFF就没生效 -
log_output决定日志去哪——FILE写文件,TABLE写mysql.general_log表,FILE,TABLE表示双写(不推荐) - 如果
log_output是TABLE,但mysql.general_log表为空,可能是表被禁用或权限不足(需要SUPER权限才能写入该系统表)
临时开启 general_log(推荐排查时用)
无需重启 MySQL,适合快速抓包式诊断。但注意:这些设置在服务重启后丢失。
- 先确保有
SUPER权限(普通用户执行会报ERROR 1227 (42501)) - 执行:
SET GLOBAL general_log = ON; - 指定日志路径(可选,但强烈建议):
SET GLOBAL general_log_file = '/var/log/mysql/general.log';,路径目录必须由mysql用户可写,否则日志静默失败 - 若想改输出目标(比如从
FILE切到TABLE):SET GLOBAL log_output = 'TABLE';,但切换后旧日志不会自动迁移
永久开启 general_log(my.cnf 配置)
适用于测试环境或需持续监控的场景,但上线前务必评估磁盘与性能压力。
- 编辑
/etc/my.cnf或/etc/mysql/my.cnf,在[mysqld]段下添加:
general_log = 1 general_log_file = /var/log/mysql/general.log log_output = FILE
general_log = 1 和 = ON 等价,MySQL 会识别;log_output 必须显式设为 FILE,否则某些版本默认是 TABLE,而 TABLE 方式在高并发下易引发锁争用sudo systemctl restart mysql(或 mysqld)SHOW VARIABLES LIKE 'general_log%'; 验证是否加载成功实时查看和清理日志的注意事项
日志不是开了就能“看到”,得配合工具和权限一起用。
- 文件方式:用
tail -f /var/log/mysql/general.log实时追加,但注意日志无自动轮转,大流量下几小时就可能占满磁盘 - 表方式:查
SELECT * FROM mysql.general_log ORDER BY event_time DESC LIMIT 50;,但该表不带索引,数据量大时查询极慢;且 MySQL 8.0+ 中该表默认被禁用(skip_general_log),需手动解除 - 清理策略:文件日志用
logrotate配置自动切割;表日志需定期TRUNCATE TABLE mysql.general_log;(不能用DELETE,否则自增 ID 溢出) - 敏感信息:日志里会明文记录
INSERT、UPDATE的值,包括密码字段——如果业务表里存了明文密码,general_log会一并记下
真正难的不是“怎么开”,而是判断“要不要开”和“开多久”。一个未加索引的 SELECT * 在 100 万行表上跑一次,general_log 就多记几百 KB;而并发 100 连接持续写,1 小时就能生成 GB 级日志。别让日志本身成为压垮系统的最后一根稻草。


















