MySQL 默认不记录权限变更,必须手动启用审计插件
直接回答:
GRANT、
REVOKE、
CREATE USER这类语句,MySQL 社区版默认**完全不记日志**——
general_log和
binlog都靠不住。你翻遍
/var/log/mysql/也找不到一条权限操作记录,这不是配置错了,是设计如此。
用 server_audit 插件捕获 QUERY_DDL 事件(社区版最稳方案)
这是目前社区版 MySQL 最可靠、最轻量的权限审计方式,核心就三步:
确认插件文件存在:ls /usr/lib/mysql/plugin/server_audit.so(路径可能为
/usr/lib64/mysql/plugin/或通过
SHOW VARIABLES LIKE 'plugin_dir';查) 安装并启用:
INSTALL PLUGIN server_audit SONAME 'server_audit.so';关键配置(必须设
QUERY_DDL):
SET GLOBAL server_audit_events = 'CONNECT,QUERY_DDL';<br>SET GLOBAL server_audit_logging = ON;<br>SET GLOBAL server_audit_file_path = '/var/log/mysql/audit.log';
⚠️ 注意:
QUERY_DML不管用,它只抓
INSERT/UPDATE/DELETE;只有
QUERY_DDL才覆盖权限语句。日志里会清晰出现:
"query":"GRANT SELECT ON test.* TO 'dev'@'10.0.1.%'",带
user、
host、
timestamp字段。
别碰 general_log —— 它不是审计工具,是排查陷阱
虽然
general_log看似“啥都记”,但它在权限审计场景下基本无效: 日志无结构:
GRANT ...和
SELECT COUNT(*) FROM orders混在同一行,无法自动提取、过滤或告警 无用户上下文分离:所有语句都标记为“连接用户”,但实际执行者可能是代理账号、中间件或应用池,
general_log不记录
proxy_user或
external_user性能爆炸:开启后 QPS 下降 15–30%,日志体积每天 GB 级,磁盘 I/O 成瓶颈 不记录执行结果:
GRANT ON nonexistent_db.*失败了?
general_log照样记,但没标
error_code,你得再查错误日志对齐时间戳
企业版 audit_log 或 Percona Audit Plugin 是替代选项
如果你用的是 MySQL Enterprise Edition,直接配
audit_log.so更省心:
[mysqld]<br>plugin-load = audit_log.so<br>audit_log_format = JSON<br>audit_log_policy = ALL<br>audit_log_file = /var/log/mysql/audit.log
Percona Server 用户可装
percona-server-audit-plugin,支持 CSV/JSON、按用户/库过滤,且性能比
server_audit更低。但注意:所有插件都要求重启或至少重载配置,且日志路径目录需 MySQL 进程有写权限(
chown mysql:mysql /var/log/mysql),否则插件加载成功但日志静默失败——这个坑很多人踩过。
真正难的不是开日志,而是把日志变成可用线索:轮转策略(
server_audit_file_rotate_on_size)、归档脚本、权限控制(
chmod 600 /var/log/mysql/audit.log)、与 ELK/Splunk 对接——这些才是上线后马上要补上的动作。
