如何查看 MySQL 最近执行过的查询?
查看 MySQL 最近执行查询的三种方式:general log 输出到表或文件、performance_schema 语句历史、慢查询日志;附临时开启命令、性能开销提醒与 FAQ。
临时排查最直接:开 MySQL 的 general log——SET GLOBAL log_output='TABLE'; SET GLOBAL general_log='ON';,然后查 mysql.general_log 表就能看到所有执行过的语句。 查完记得关掉,它开销不小。
方法一:general log 输出到表
SET GLOBAL log_output = 'TABLE';
SET GLOBAL general_log = 'ON';
-- 看最近的查询
SELECT event_time, user_host, command_type, argument
FROM mysql.general_log
ORDER BY event_time DESC
LIMIT 50;
查完务必关闭(下面详述)。
方法二:general log 输出到文件
SET GLOBAL log_output = 'FILE';
SET GLOBAL general_log_file = '/var/log/mysql/general.log';
SET GLOBAL general_log = 'ON';
然后 tail -f /var/log/mysql/general.log 实时观察。注意:MySQL 进程要对该路径有写权限。
方法三:不重启的历史——performance_schema
MySQL 5.6+ 的 performance_schema 默认记录了最近语句(无需开 general log):
SELECT event_id, thread_id, sql_text, timer_wait/1e12 AS seconds
FROM performance_schema.events_statements_history_long
WHERE sql_text IS NOT NULL
ORDER BY event_id DESC
LIMIT 20;
容量有限(默认最近 10000 条),且只记录执行过的语句、不含连接/断开事件——但对"刚才那条 SQL 到底是什么"足够用。
方法四:慢查询日志(生产推荐)
general log 不适合常开,但慢查询日志应该常开:
# my.cnf
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1 # 超过 1 秒的记录
log_queries_not_using_indexes = 1
重要:用完关掉 general log
SET GLOBAL general_log = 'OFF';
general log 记录每一条语句,高并发下既是 CPU/IO 负担也是磁盘炸弹,还可能把敏感数据写进日志——只用于短时排查。
观测云对照
与其临时开 general log 救火,不如把数据库可观测性常态化:观测云的数据库集成可采集慢查询日志与性能指标,在日志查看器里按执行时长、来源用户聚合分析;慢查询数量突增、特定表的全表扫描都能配成告警,SQL 层面的退化在影响业务前就能被发现。
常见问题(FAQ)
Q:general_log 表越来越大怎么办?
A:关掉 general log 后 TRUNCATE mysql.general_log; 清空。它默认是 CSV 引擎,别在高负载时对它做复杂查询。
Q:能看到某个具体用户执行的查询吗?
A:general log 的 user_host 列有来源账户;performance_schema 可关联 threads 表按 processlist_user 过滤。
Q:能看到正在执行(还没执行完)的查询吗?
A:那是另一件事——SHOW FULL PROCESSLIST; 或查 information_schema.processlist,能看到当前活动连接和正在跑的 SQL。