mysql slow_log 默认不脱敏,log_slow_extra仅添加执行计划等元信息而不处理sql文本,官方无内置脱敏能力,需客户端拦截或日志管道清洗实现。

slow_log里为什么还是能看到明文密码和敏感字段
MySQL的slow_query_log默认不脱敏,哪怕开了log_slow_extra,它只加执行计划、锁等待等元信息,对SQL文本本身完全不做处理。你看到的SELECT * FROM users WHERE token = 'abc123',照样原样记进日志。
-
log_slow_extra是“额外信息开关”,不是“脱敏开关”——名字有误导性,别被带偏 - 真正影响日志内容的是
log_output(决定写文件还是表)和long_query_time(触发阈值),但都不碰SQL字符串本身 - MySQL官方至今没提供内置SQL脱敏能力,所有“安全输出”都得靠外部手段兜底
用general_log做脱敏日志是否可行
不行。general_log比慢日志更危险:它记录所有语句,包括SET PASSWORD、INSERT INTO config这类高危操作,且同样无脱敏机制。开启后磁盘暴涨、性能骤降是常态,生产环境基本等于自废武功。
-
general_log默认关着是有道理的——它连SELECT 1都记,日志体积不可控 - 哪怕你用脚本实时过滤
general_log文件,也存在时间窗口:敏感语句已落盘,再删也晚了 - MySQL 8.0+ 的
audit_log插件支持规则过滤,但仅限于拒绝/放行,不支持重写SQL内容
实际能落地的脱敏方案只有两种
要么在客户端层拦截改写SQL,要么在日志采集侧做流式清洗。MySQL服务端自己不干这事,得你主动切出去做。
- 应用层改写:所有发往MySQL的查询,在拼SQL前把
WHERE password = ?替换成WHERE password = '[REDACTED]',用ORM参数绑定时注意toString()调试输出也要同步处理 - 日志管道清洗:用Filebeat或Fluentd监听
slow.log文件,匹配WHERE.*=.*'[^']+'这类正则,把单引号内内容替换为[MASKED];注意避开INSERT INTO log VALUES ('...')这种合法含单引号的场景 - 别信“修改mysqld源码打patch”的方案——升级就废,且MySQL 8.0+的parser模块耦合度极高,改错一行可能让整个SQL解析崩溃
log_slow_extra开启后反而暴露更多风险点
log_slow_extra会额外记录Rows_examined、Lock_time、Query_time,看起来很专业,但如果你的日志权限没收紧,攻击者通过分析Rows_examined能反推出表数据量级,结合Query_time还能估算索引有效性——这些都属于侧信道信息。
- 确认
slow_query_log_file路径不在Web可访问目录下,比如别放在/var/www/html/里 - Linux上必须用
chown mysql:mysql+chmod 600锁死日志文件权限,MySQL进程以外的用户连读都不行 - 如果用
log_output = TABLE写入mysql.slow_log表,记得给该表加行级审计策略,避免DBA账号被横向提权后直接SELECT全量慢查
真正麻烦的从来不是“怎么开日志”,而是“谁能看到、能看到多少、看到后能推导出什么”。脱敏不是加个配置就能完事的事。











