mysql社区版默认不记录grant等权限操作,需用server_audit插件实现可靠审计:它结构化记录user、host、status等字段,必须显式启用query_ddl事件,且不可与general_log共存。

MySQL 社区版默认完全不记录 GRANT、REVOKE、CREATE USER 等权限操作——这不是配置遗漏,是设计如此。想可靠监控“谁在什么时候改了权限”,不能靠猜,得选对工具、配对参数、避开常见断点。
为什么 general_log 不能当权限审计用
它确实会记下 GRANT 语句,但只是作为普通文本混在海量日志里,没有结构、没上下文、没执行结果,根本没法自动化提取或告警。
- 日志里只有一行:
GRANT SELECT ON db.* TO 'u'@'%',但没字段标出user、host、timestamp,更不会告诉你这条语句是成功还是报错(比如库不存在) - 所有连接、
SELECT、SET都挤在一起,grep"grant"只能人工翻,漏掉大小写或空格就丢事件 - 开启后 QPS 明显下降,日志文件每小时涨几百 MB,磁盘 I/O 成瓶颈,且 MySQL 不自动轮转,得靠外部脚本兜底
- 如果应用走中间件(如 ProxySQL、ShardingSphere),
user@host记的是中间件账号,不是真实操作人
server_audit 插件才是社区版唯一靠谱方案
它专为审计设计,原生识别权限类 DDL,并打上 QUERY_DDL 标签,每条日志自带 user、host、query、status(0=成功,非0=失败)等结构化字段。
- 必须显式启用
QUERY_DDL:执行SET GLOBAL server_audit_events = 'CONNECT,QUERY_DDL';,漏掉这句就等于没开权限审计 - 插件文件路径需先确认:
SHOW VARIABLES LIKE 'plugin_dir';,再查对应目录下是否有server_audit.so - 日志路径建议独立设置:
SET GLOBAL server_audit_file_path = '/var/log/mysql/audit.log';,然后chown mysql:mysql /var/log/mysql防篡改 - 避免和
general_log共存——两者同时开会导致性能叠加下降,且日志内容互相干扰,毫无协同价值
audit_log 插件只在企业版或特定发行版可用
如果你用的是 MySQL 8.0 社区版,执行 INSTALL PLUGIN audit_log SONAME 'audit_log.so'; 很可能报错 “Plugin 'audit_log' is not loaded”,因为官方社区版根本不带这个插件。
- MySQL 5.7 企业版、MySQL 8.0 企业版才内置
audit_log;Percona Server 或 MariaDB 用户可尝试兼容版本 - 即使加载成功,也要检查输出模式:
SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'audit_log';,状态为ACTIVE才算真正启用 - 关键配置项如
audit_log_policy = ALL和audit_log_format = JSON必须写进my.cnf并重启,动态 SET 不生效 -
FLUSH PRIVILEGES这种操作不会被记录——它不触发 SQL 执行事件,audit_log 完全感知不到
binlog 解析只能作为最后手段
当所有插件都不可用、又恰好开了 binlog_format = ROW 且保留了足够久的 binlog 时,才能从系统表变更中反推权限修改。
-
GRANT语句本身不会出现在 binlog 里,它会被转成对mysql.user、mysql.db等表的UPDATE或INSERT操作 - 解析命令要加
--base64-output=DECODE-ROWS -v,再配合grep -E "(UPDATE.*mysql\.user|INSERT.*mysql\.db)"过滤 - 时间范围必须收紧:
--start-datetime="2026-05-05 10:00:00" --stop-datetime="2026-05-05 11:00:00",否则全量解析极慢 - 直接改系统表(如
UPDATE mysql.user SET ...)也会被记录,但语义模糊,需人工比对字段含义,容易误判
最常被忽略的一点:无论用哪种方式,FLUSH PRIVILEGES 和存储过程封装的权限操作(如 CALL set_perms())都不会暴露真实授权意图——前者无日志,后者只记调用语句。真要覆盖这类盲区,得结合工单系统与权限审批流程,日志只是最后一道防线。











