MySQL 中如何记录执行过的所有 SQL 查询?
MySQL 记录所有查询:SET GLOBAL general_log='ON' 开启通用查询日志,log_output 可选 TABLE(存 mysql.general_log 表)或 FILE。注意性能开销大,仅短期调试。
运行时开启:SET GLOBAL general_log = 'ON';。输出目标由 log_output 控制:'TABLE' 存到 mysql.general_log 表(直接 SELECT 查看),'FILE' 写入日志文件。注意:全量记录性能开销大,只适合短期调试。
方式一:记录到表(便于查询)
SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';
-- 查看查询历史
SELECT * FROM mysql.general_log ORDER BY event_time DESC LIMIT 20;
方式二:记录到文件
SET GLOBAL log_output = 'FILE';
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/all-queries.log';
SET GLOBAL 通常仅作用于当前服务器运行期;log_output 同时影响 general log 与 slow log,调试前记录旧值,完成后按需恢复。路径需 mysqld 有写权限。
永久生效(配置文件)
# my.cnf
[mysqld]
general_log = 1
log_output = FILE
general_log_file = /var/log/mysql/mysql.log
用完记得关
SET GLOBAL general_log = 'OFF';
general log 主要记录服务器收到的连接与语句(包括 SELECT),并不证明执行成功、完成顺序或事务提交;高并发下会显著拖慢数据库并快速占满磁盘。
更实用的替代:慢查询日志
日常排查性能问题用慢查询日志更合适(开销小):
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
-- 新连接继承全局值;现有目标会话需 SET SESSION long_query_time = 1
常见问题(FAQ)
Q:general log 对性能影响多大?
A:每条查询多一次磁盘/表写入,高并发场景吞吐可能下降明显。仅用于短期抓"程序到底发了什么 SQL"。
Q:只想看某张表的查询?
A:general log 不支持按表过滤。可以在 TABLE 输出模式下 SELECT * FROM mysql.general_log WHERE argument LIKE '%表名%',但文本匹配会误命中注释/值,也可能漏掉别名或间接访问,不能当精确表审计。
Q:记录的密码会明文显示吗?
A:CREATE USER/GRANT 等含密码的语句会被改写隐藏密码,但应用 SQL 中的敏感参数是明文——注意日志文件的权限。