mysql慢查询日志默认不记录host/user,因文件模式下user@host字段始终为空;需设log_output='table'并手动创建mysql.slow_log表才能保存连接信息。

slow_query_log默认不记录Host/User,因为日志格式不包含连接上下文
MySQL慢查询日志默认只记录SQL文本、执行时间、锁等待时间等执行指标,Host 和 User 字段不会写入日志文件——这不是权限或配置错误,而是日志格式设计如此。日志行结构固定为:# Time: ... # User@Host: ... # Query_time: ... # Lock_time: ... SET timestamp=...; ...,但其中的User@Host字段仅在log_output = 'TABLE'且mysql.slow_log表存在时才由MySQL内部填充;写入文件时,该字段**始终为空**(显示为# User@Host:后直接换行),哪怕你用mysql -h10.0.1.2 -uapp_user连接也看不到来源信息。
想看到Host/User必须用TABLE输出模式 + 确保mysql.slow_log表已创建
只有当log_output = 'TABLE'且mysql.slow_log表存在时,MySQL才会把连接的host和user存进表字段。但这个表不是自动建的——首次启用慢日志时,MySQL不会帮你创建它,必须手动执行:
CREATE TABLE IF NOT EXISTS mysql.slow_log (
start_time TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
user_host MEDIUMTEXT NOT NULL,
query_time TIME(6) NOT NULL,
lock_time TIME(6) NOT NULL,
rows_sent INTEGER NOT NULL,
rows_examined INTEGER NOT NULL,
db VARCHAR(512) NOT NULL,
last_insert_id INTEGER NOT NULL,
insert_method ENUM('INSERT', 'REPLACE', 'IGNORE') DEFAULT NULL,
server_id INTEGER UNSIGNED NOT NULL,
sql_text MEDIUMTEXT NOT NULL,
thread_id INTEGER NOT NULL
) ENGINE=CSV;
注意:user_host字段是合并存储的(如'app_user[app_user] @ 10.0.1.2 [10.0.1.2]'),不是分开的user/host列;ENGINE=CSV是官方推荐(避免InnoDB锁表影响写入)。
- 确认当前输出方式:
SHOW VARIABLES LIKE 'log_output';,如果不是'TABLE',先设SET GLOBAL log_output = 'TABLE'; - 检查表是否存在:
SHOW TABLES IN mysql LIKE 'slow_log'; - 如果表存在但
user_host仍为空,说明该次查询来自SQL线程(如从库复制),此时user_host固定为'NULL'@'NULL',无法改写
FILE模式下强行加Host/User?只能靠代理层或客户端注释
如果你坚持用log_output = 'FILE'(比如为了用pt-query-digest分析),MySQL本身不支持往日志文件里注入Host/User。可行的绕过方式只有两种:
- 在应用层所有查询前加注释,例如:
/* app_user@10.0.1.2 */ SELECT * FROM orders WHERE ...,这样日志里就能看到来源标识(但依赖开发规范,且不防伪造) - 用ProxySQL或MaxScale这类中间件,在转发时自动注入
/* client_ip=10.0.1.2, user=app_user */,再让MySQL原样记入日志 - 不要试图改MySQL源码或用
general_log替代——general_log虽含User@Host,但会记录所有语句(包括健康检查、心跳),日志爆炸且无耗时筛选能力
云数据库(RDS/CDB)基本没得选,TABLE模式是唯一路径
阿里云RDS、腾讯云CDB等托管服务默认禁用log_output = 'FILE',只允许写入mysql.slow_log表。这意味着你根本没法拿到原始日志文件,更别说修改格式。此时必须:
- 确认
slow_query_log = ON且log_output = 'TABLE' - 手动建
mysql.slow_log表(如上),否则日志直接丢弃(不会报错) - 查日志时用:
SELECT user_host, query_time, sql_text FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10; - 注意:RDS控制台展示的“慢SQL列表”通常就是查这个表,但部分厂商会过滤掉
user_host字段,需直接连上去查表
真正容易被忽略的是:即使开了log_output = 'TABLE',如果mysql.slow_log表不存在,MySQL会静默放弃记录——不会警告,也不会尝试建表,日志就彻底消失了。











