如何查看 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 通常在接收时记录,不证明执行完成或成功。 查完记得关掉,它开销不小。
方法一: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 和 log_output;后者也影响慢查询日志,排查后恢复原配置,而非一律关闭原本已启用的日志。
方法二: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
是否有历史取决于 Performance Schema、statement instrumentation 和 consumers;events_statements_history_long 并非始终默认启用,需检查 setup_consumers:
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 timer_start DESC
LIMIT 20;
容量按版本和启动配置决定;EVENT_ID 在各线程内计数,不能跨线程按它排序,且只记录执行过的语句、不含连接/断开事件——但对"刚才那条 SQL 到底是什么"足够用。
方法四:慢查询日志(生产推荐)
general log 不适合常开,慢查询日志可按负载、敏感数据和保留策略评估开启:
# my.cnf
[mysqld]
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 配置
-- 仅当排查前为 OFF 时恢复为 OFF
SET GLOBAL general_log = 'OFF';
general log 记录每一条语句,高并发下既是 CPU/IO 负担也是磁盘炸弹,还可能把敏感数据写进日志——只用于短时排查。
常见问题(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。