可通过SET GLOBAL general_log = ON临时开启general_log,配合SET GLOBAL log_output指定FILE或TABLE输出,无需重启MySQL;永久配置需在my.cnf的[mysqld]段添加general_log、log_output和general_log_file参数并重启服务;生产环境应避免启用,因其记录所有SQL、开销大、泄露敏感信息且无日志轮转。

如何通过 SET 命令临时开启 general_log
直接生效、无需重启 MySQL,适合快速验证日志内容或排查偶发问题。但仅对当前会话或全局临时有效,服务重启后丢失。
操作分两步:
- 启用日志开关:
SET GLOBAL general_log = ON; - 指定日志输出目标(文件或表):
SET GLOBAL log_output = 'FILE';或SET GLOBAL log_output = 'TABLE';
若选 FILE,默认写入 hostname.log(路径由 general_log_file 变量决定);若选 TABLE,日志存入 mysql.general_log 表,需注意该表是 CSV 引擎,不支持索引,查询效率低且无法 truncate(只能用 SET GLOBAL general_log = OFF; 后手动清空或删表重建)。
如何在 my.cnf 中永久配置 general_log
修改配置文件后必须重启 MySQL 才能生效,适合测试环境长期观察,但生产环境慎用。
在 [mysqld] 段下添加:
general_log = ON log_output = FILE general_log_file = /var/log/mysql/general.log
注意三点:
-
general_log_file路径需确保 MySQL 进程有写权限,否则启动失败或静默丢弃日志 - MySQL 5.7+ 默认关闭
log_output的TABLE选项(因性能和安全顾虑),如需启用需额外加log_output = TABLE,FILE - 配置项名是
general_log,不是general_log_on或enable_general_log,拼错会导致无效
为什么生产环境几乎不该开 general_log
它记录**每一条**客户端发送的 SQL(含 SELECT),无过滤、无采样、无条件,I/O 和 CPU 开销随并发线程数线性增长。
典型风险包括:
- 单次简单查询可能产生 2–3 行日志(连接、查询、断开),QPS 1000 时日志写入量轻松超 2MB/s,磁盘 I/O 成瓶颈
- 敏感信息明文落盘:账号密码(如
mysql -uadmin -ptest123连接)、SQL 中的手机号、身份证号、token 全部可见 - 日志文件无自动轮转机制(
logrotate无法安全重命名正在写的.log文件),容易撑爆磁盘 - 开启后
SHOW PROCESSLIST响应变慢,因为内部要同步日志状态
生产环境替代方案:用 slow_query_log + long_query_time=0
如果真需要全量 SQL 审计,优先考虑更可控的方式:
- 启用慢日志并设
long_query_time = 0(MySQL 5.6.12+ 支持),它走的是优化器执行路径,比general_log开销低 30%–50% - 配合
log_queries_not_using_indexes = ON可捕获缺失索引的查询,兼顾性能分析 - 使用
pt-query-digest工具解析慢日志,支持聚合、排序、去重,比人工翻general_log实用得多 - 如需实时采集,用 MySQL 8.0+ 的
performance_schema.events_statements_history_long表(内存中,可动态开关,无磁盘压力)
真正需要通用日志的场景极少——比如驱动层协议调试、极早期兼容性验证。多数所谓“查不到某条 SQL”问题,其实是没意识到应用用了连接池、SQL 被改写、或日志根本没写到预期位置。











