mysql审计插件需设audit_log_policy=all且audit_log_format=json,再通过grep提取用户名日志;audit_log_file须为绝对路径并确保mysql用户有写权限;日志中user字段仅标识连接用户,无法精确溯源终端操作人。

MySQL 审计插件本身不支持按用户名过滤写入日志,必须靠配置 + 日志后处理实现“追踪特定用户”——直接在插件层设白名单会漏掉关键事件(如登录失败),而全量记录再筛选才是可靠做法。
audit_log_policy=ALL 是唯一能覆盖完整行为链的选项
很多人误以为用 audit_log_policy=LOGINS 就能盯住目标用户,但这样只记录连接/断开,漏掉后续所有 SQL 操作。真正要追踪“张三干了什么”,必须捕获从 CONNECT 到 QUERY 再到 DISCONNECT 的完整链条:
-
LOGINS:只记connect和disconnect事件,查不到他执行了哪条 DELETE -
COMMANDS:跳过连接事件,无法关联 IP、时间戳和用户身份,日志里只有孤立的query记录 -
ALL:强制记录全部事件类型,包括connect(含user、ip、status)、query(含sql_text)、disconnect,才能拼出完整操作轨迹
JSON 格式下 grep 用户名才真正可靠
audit_log_format=JSON 是必须项,否则你根本没法精准提取目标用户。NEWLINE 格式字段顺序依赖版本,且失败登录可能不输出 IP;而 JSON 每行都有明确字段:
- 成功登录:
"name":"connect","user":"zhangsan","host":"10.0.1.5","status":0 - 失败登录:
"name":"connect","user":"zhangsan","host":"10.0.1.5","status":1045 - 执行语句:
"name":"query","user":"zhangsan","sql_text":"DELETE FROM orders WHERE id=123" - 用
grep '"user":"zhangsan"' /var/log/mysql/audit.log即可提取全部相关行,无需解析字段位置
audit_log_file 路径错误是日志“消失”的最常见原因
插件加载成功、策略也设对了,但日志文件就是空——90% 是因为 audit_log_file 指向了 MySQL 进程无权写入的位置:
- 路径必须是绝对路径,
/var/log/mysql/audit.log可行,./audit.log或~/audit.log会被忽略 - 目录需由
mysql用户(或运行 mysqld 的系统用户)拥有写权限:chown mysql:mysql /var/log/mysql,chmod 750 /var/log/mysql - 避免路径含中文、空格、软链接循环;SELinux 启用时需确认 context:
ls -Z /var/log/mysql,必要时semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?" - 不要指望插件自动创建父目录——
/var/log/mysql必须提前存在
真正难的是区分“谁执行了语句”和“谁触发了变更”
审计日志里的 user 字段只反映当前连接的认证用户,不等于实际操作人。比如:
- 应用用
app_user连接,但业务逻辑里调用存储过程,日志里所有query都标为app_user,而非最终调用该过程的前端用户 - DBA 用
root登录后执行SET SESSION sql_log_bin=0,部分 DML 可能绕过 binlog,但 audit_log 仍会记录 - 连接池复用下,
user字段不变,但实际执行者可能是不同应用线程——这时得结合thread_id和应用层 traceID 关联
别指望单靠 audit_log 精确锁定终端操作人,它只保证“这个账号在什么时间做了什么”,更细粒度溯源得靠应用埋点或 proxy 层日志。











