mysql 8.0企业版才原生支持audit_log插件追踪特权操作;社区版因缺失audit_log.so文件,执行install plugin必失败。须先用select version()确认含enterprise字样,再查plugins表状态,加载后set global audit_log_policy='all'方可捕获grant/revoke等操作。

MySQL 8.0 企业版才能用原生 audit_log 插件追踪特权操作;社区版即使执行 INSTALL PLUGIN audit_log 也会失败,因为 audit_log.so 文件根本不存在。
确认你用的是 MySQL 企业版
社区版用户看到这里就可以停了——不是配置错,是压根没这个插件。企业版才自带 audit_log.so,且默认不加载。
验证方式只有一条:SELECT PLUGIN_NAME, PLUGIN_STATUS FROM information_schema.PLUGINS WHERE PLUGIN_NAME = 'audit_log';
- 有结果且状态为
ACTIVE→ 可继续 - 返回空或状态为
DISABLED→ 检查是否为企业版(SELECT VERSION();输出含Enterprise字样) - 报错
Unknown table 'information_schema.PLUGINS'或无此表 → 版本太低或权限不足
加载插件并启用 ALL 策略
audit_log_policy 必须设为 ALL 才能捕获 GRANT、REVOKE、DROP USER、SET PASSWORD 等特权操作。设成 LOGINS 或 QUERIES 都会漏掉关键事件。
操作分两步,缺一不可:
- 运行时加载:
INSTALL PLUGIN audit_log SONAME 'audit_log.so'; - 全局启用:
SET GLOBAL audit_log_policy = 'ALL';
注意:audit_log_policy 是动态变量,但 audit_log_file 和 audit_log_format 必须在 my.cnf 中配置并重启生效,运行时设置无效。
JSON 格式日志里怎么快速定位特权操作
特权操作在 JSON 日志中统一标记为 "command_class":"grant"、"command_class":"revoke"、"command_class":"user_admin"(如 DROP USER)、"command_class":"set_option"(如 SET PASSWORD)。
别直接 cat 整个日志文件——它不换行、无缩进。推荐实时过滤命令:
- 查所有权限变更:
tail -f /var/lib/mysql/audit.log | jq -r 'select(.command_class == "grant" or .command_class == "revoke") | "\(.timestamp) \(.user) \(.query)"' - 只看用户管理类:
grep -E '"command_class":"(user_admin|set_option)"' /var/lib/mysql/audit.log | jq -r '.user, .query, .timestamp'
⚠️ query 字段明文记录 SQL,含密码的 SET PASSWORD 也会裸露。生产环境必须限制 /var/lib/mysql/audit.log 权限为 600,属主为 mysql。
audit_log 不解决“谁删了哪行”,binlog 才是最终手段
审计日志只告诉你“谁执行了 DROP TABLE”,但不记录被删的是哪几行数据;它也抓不到 UPDATE 的旧值和新值。
若真实目标是追溯误删、误更新,必须开启 ROW 格式 binlog 并配齐三项:
binlog_format = ROWbinlog_row_image = FULLbinlog_rows_query_log_events = ON
三者缺一不可。开启后,用 mysqlbinlog --base64-output=DECODE-ROWS -v 解析,才能看到原始 SQL + 具体变更的行级内容。











