audit_log插件仅mysql社区版8.0.19+内置支持,5.7社区版不兼容;需通过select version()和show plugins确认版本与状态,配置必须写入my.cnf并重启生效,且audit_log_format=json不可省略。

audit_log插件是否可用,先看版本和状态
MySQL社区版 8.0.19+ 才内置 audit_log 插件;5.7 系列只有企业版支持,社区版装了也报错 Plugin 'audit_log' is not loaded。别急着改配置,先确认基础条件:
- 运行
SELECT VERSION();,低于8.0.19的社区版直接放弃该插件方案 - 执行
SHOW PLUGINS LIKE 'audit_log';,输出为空或Status是DISABLED,后续所有配置都无效 - 注意:MariaDB 用的是
server_audit,和 MySQL 的audit_log不兼容,别混用
配置必须写进 my.cnf,重启才生效
INSTALL PLUGIN audit_log SONAME 'audit_log.so'; 只是临时加载,mysqld 一重启就消失。真正要持久化,必须在 [mysqld] 段加这三行:
plugin_load_add = audit_log.so audit_log = FORCE_PLUS_PERMANENT audit_log_format = JSON
缺一不可。特别注意:audit_log_format = JSON 必须显式设置——旧的 NEWLINE 格式没有 status 字段,根本分不清 SELECT 是成功还是被拒绝。
-
audit_log_policy = COMMANDS是底线,它能捕获所有SELECT/INSERT/UPDATE/DELETE,但不包括GRANT这类权限操作 - 真要盯权限变更,得设
audit_log_policy = ALL,但高并发下 IO 压力陡增,磁盘写满风险很高 - 想只监控几张表?MySQL 8.0.22+ 支持
audit_log_include_tables = 'user_info,payment_log'(逗号分隔、无空格)
日志路径和权限最容易踩坑
默认日志写进 error_log 文件,和崩溃、复制错误混在一起,查可疑行为等于大海捞针。必须单独指定路径:
audit_log_file = /var/log/mysql/audit.json
但光写路径没用,还得确保两件事:
-
mysqld进程用户(通常是mysql)对目标目录有写权限,chown mysql:mysql /var/log/mysql比chmod 777安全得多 - SELinux 开启时,需打标签:
semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?",否则写入失败静默丢日志 - 日志不会自动轮转,得靠
logrotate配置,否则单个文件可能撑爆磁盘
登录失败和权限变更得用别的方案补位
audit_log 插件不记录登录失败(Access denied)和 GRANT 类语句(除非设 ALL)。这两类关键行为得靠组合策略:
- 登录失败:设
log_warnings = 2,然后grep "Access denied" /var/log/mysql/error.log。注意using password: NO比YES更可疑,可能是撞库扫号 - 权限变更:MySQL 8.0.14+ 可用
performance_schema抓statement/abstract/account_management事件,查events_statements_history_long表里的GRANT语句,重点看HOST是否为%或非常规网段 -
general_log虽能记所有连接,但性能开销大、无上下文,仅适合临时排查,不能当审计主通道
audit_log 的 JSON 日志字段丰富,但解析依赖工具链;而 error_log 和 performance_schema 数据分散,得靠脚本串联。真正落地时,没人只靠一个开关就搞定“异常访问”——它本质是多个日志源的交叉验证过程。











