MySQL 8.0.19+ 原生支持 audit_log 插件,需用 SYSTEM_VARIABLES_ADMIN 和 SYSTEM_USER 权限执行 INSTALL PLUGIN audit_log SONAME 'audit_log.so' 加载,并配置 audit_log_policy 等参数生效。

MySQL 8.0+ 审计插件名和加载方式
MySQL 自带的审计功能依赖 audit_log 插件,但注意:它不是默认启用的,也不是所有版本都内置——仅 MySQL 8.0.19+ 社区版及企业版原生支持;早于该版本或某些定制包可能根本没编译这个插件。
确认是否存在:SHOW PLUGINS; 查看输出中是否有 audit_log 行,状态为 ACTIVE;若没有,先检查 plugin_dir 路径下是否存在 audit_log.so(Linux)或 audit_log.dll(Windows)文件。
- 加载命令是
INSTALL PLUGIN audit_log SONAME 'audit_log.so';,不是LOAD PLUGIN - 必须用有
SYSTEM_VARIABLES_ADMIN和SYSTEM_USER权限的账户执行(root 通常满足,普通 DBA 账户可能缺后者) - 插件加载后不会自动写日志,还需显式配置参数,否则看似“启用”实则静默
audit_log 相关关键参数怎么设才生效
插件加载后,日志行为由几个全局变量控制,改完必须 SET PERSIST 或写进配置文件,重启才真正持久化。只用 SET GLOBAL 是临时的,升级后重启就丢。
-
audit_log_policy:决定记录范围,常用值是ALL(登录+查询+管理命令)、LOGINS(仅连接/断开)、QUERIES(仅 SQL 执行)。设成VALIDATE会直接报错,别试 -
audit_log_format:推荐JSON,比NEWLINE更易解析;但注意 MySQL 8.0.22 前 JSON 格式不包含客户端 IP,升级后务必验证字段完整性 -
audit_log_file:路径需 MySQL 进程有写权限,且不能和 error log / slow log 写同一目录(某些 SELinux 策略会拦截) -
audit_log_strategy:选ASYNCHRONOUS,避免日志写失败拖慢查询;但极端情况下可能丢少量日志,生产环境要权衡
为什么开了 audit_log 却看不到日志文件
最常见原因不是配置错,而是权限和上下文不匹配:MySQL 启动用户(如 mysql 用户)对 audit_log_file 指定路径无写权限,或者路径父目录不存在。
- 检查路径:运行
SELECT @@audit_log_file;,然后在系统里执行sudo -u mysql touch /path/to/audit.log,看是否报 permission denied - SELinux:CentOS/RHEL 上默认阻止 MySQL 写自定义路径,临时关可用
setsebool -P mysqld_read_default_logs on,但更安全的是用auditctl规则放行 - 日志轮转:MySQL 不自带 rotate 功能,
audit_log_rotate_on_size参数仅在企业版支持,社区版得靠外部脚本 +FLUSH LOGS配合 - 注意:即使配置全对,首次写日志也发生在**第一个满足 policy 的事件之后**,不是插件加载瞬间
审计日志权限最小化配置要点
审计本身需要高权限,但读取和归档日志不应暴露给所有 DBA。别把 SELECT 权限直接给 mysql 库——审计日志不在表里,而是在文件系统里。
- 日志文件属主应为
mysql:mysql,权限设为640,禁止 world 可读 - 归档脚本若用 cron 执行,建议新建专用系统用户(如
audit-rotator),通过sudoers限制其只能运行FLUSH LOGS和移动文件 - 不要在 MySQL 配置里硬编码密码或密钥;如果用远程 syslog,确保
audit_log_socket或audit_log_server的通信走 TLS,明文发审计日志等于裸奔 - 特别注意:MySQL 8.0.33+ 对
audit_log插件增加了AUDIT_ADMIN权限要求,旧权限模型会失效
插件行为和参数含义在小版本间有细微差异,比如 8.0.27 改了 JSON 字段命名,8.0.30 修复了并发写日志崩溃问题——升级后第一件事不是调策略,是查对应版本的 audit_log release note。


















