mysql审计日志默认不记录grant操作,因社区版无原生支持,企业版audit_log需显式配置policy和过滤规则;performance_schema是5.7+无需重启的替代方案,但需启用收集并注意性能与容量限制;binlog仅记录sql文本且无执行者信息,无法精确定位操作人。

MySQL审计日志默认不记录GRANT操作
MySQL社区版自带的通用日志(general_log)和慢查询日志都不捕获权限变更;企业版的审计插件(audit_log)虽能记录,但默认关闭且GRANT属于“access control”类事件,默认不启用。直接开启audit_log后仍看不到GRANT,是因为它被归类为connect或command子类型,需显式配置过滤规则。
- 检查当前审计插件是否加载:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'audit_log'; - 确认是否启用
GRANT记录:需在配置文件中设置audit_log_policy=ALL或至少audit_log_policy=COMMANDS,并确保audit_log_include_accounts包含目标账号 - 常见错误:只设
audit_log_policy=LOGINS——这只会记录登录,GRANT完全静默
用performance_schema实时抓取GRANT语句(5.7+)
如果无法启用企业版审计插件,performance_schema是唯一无需重启、开箱即用的替代方案。它通过events_statements_history_long表捕获所有执行过的语句,包括权限操作,但默认关闭语句采集,且历史表有容量限制。
- 必须先开启语句收集:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_statements_history_long'; - 过滤
GRANT的关键是匹配SQL_TEXT字段:SELECT SQL_TEXT, USER, HOST, EVENT_TIME FROM performance_schema.events_statements_history_long WHERE UPPER(SQL_TEXT) LIKE 'GRANT%'; - 注意性能影响:开启
events_statements_history_long会增加内存占用,且该表默认仅保留10000条记录,高频环境可能被快速覆盖 - 兼容性:MySQL 5.7.3及以上支持,8.0中该表默认启用但
ENABLED仍为NO
binlog里查GRANT只能看到结果,看不到执行者
开启binlog后,GRANT操作会被记录为Query_log_event,但内容只有SQL文本和数据库名,不包含客户端IP、用户名等上下文信息。这意味着你能知道“谁改了权限”,但无法确定“谁执行了修改”——因为binlog只记录服务端视角的逻辑变更。
- 解析示例:
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000001 | grep -A2 -B2 'GRANT'可看到原始语句,但USER()或CURRENT_USER()不会出现在日志中 - 依赖
binlog_format=STATEMENT才能看到可读SQL;若为ROW格式,GRANT根本不会进binlog(权限表mysql.*不走行复制) - 风险点:误删
mysql.user表数据后靠binlog回滚?不行——GRANT不是DML,不触发ROW格式记录,且mysql库本身不在binlog复制范围内
真正能定位非法修改的组合:audit_log + 系统账号隔离
单靠日志机制不够,关键在于让每一次GRANT都可追溯到具体人。MySQL不记录操作者IP和时间戳到权限表本身,所以必须从源头控制——禁用共享账号、强制使用带标识的运维账号,并把审计日志输出到外部系统(如syslog),避免被本地篡改。
- 禁止用
root@localhost日常操作:创建专用账号如dba-prod-2024@10.%.%,绑定固定IP段,再赋予GRANT OPTION - 审计日志写入syslog时,
audit_log_strategy=SECURITY确保日志不落地到MySQL服务器磁盘,防止被删除 - 容易被忽略的一点:MySQL 8.0+ 的
role机制下,GRANT角色给用户也会触发审计事件,但事件中的USER字段显示的是被授权用户,不是执行者——得看OS_LOGIN字段才对
权限监控最麻烦的不是技术实现,而是审计日志里的USER和OS_LOGIN字段含义不同,而多数人只盯着USER看。











