MySQL 8.0.19+ 社区版内置 audit_log 插件,需在 my.cnf 配置 audit_log_file、audit_log_format 并重启启用,运行时仅 audit_log_policy 可动态设置,日志为单行 JSON 格式且不记录参数绑定值。

MySQL 8.0.19+ 社区版自带 audit_log 插件,但默认未加载、未启用,且关键参数(如日志路径、格式)必须在启动前通过配置文件设定——运行时 SET GLOBAL 修改无效。硬装旧版插件或 MariaDB 的 server_audit 会直接失败,不是权限问题,是 ABI 不兼容。
确认 audit_log 插件可用且版本匹配
低于 8.0.19 的社区版没有内置 audit_log.so,强行 INSTALL PLUGIN 会报错 ERROR 1126 (HY000): Can't open shared library 'audit_log.so'。
- 先查版本:
SELECT VERSION();—— 必须 ≥ 8.0.19 - 再查插件状态:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'audit_log';—— 返回ACTIVE或DISABLED才可继续;若无结果,说明编译时未启用该插件,需换用 Percona 审计插件 - 验证编译支持:
SHOW VARIABLES LIKE 'have_audit_log';—— 值为YES才表示可用
加载插件并启用 ALL 策略
audit_log_policy 是唯一控制审计粒度的开关,它只接受三个值:'ALL'、'LOGINS'、'QUERIES';设成 'VALIDATE' 会直接报错。注意:ALL 仍不记录 mysqldump、存储过程内动态 SQL、复制线程操作。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 用具备
SYSTEM_VARIABLES_ADMIN和SYSTEM_USER权限的账户执行:INSTALL PLUGIN audit_log SONAME 'audit_log.so'; - 立即生效:
SET GLOBAL audit_log_policy = 'ALL'; - 该设置重启后丢失,要持久化必须写入配置文件(见下一条)
audit_log_file 和 audit_log_format 必须写进 my.cnf 并重启
audit_log_file 和 audit_log_format 是只读变量,运行时赋值会被忽略。常见错误“日志没生成”“路径设了但没用”,90% 是因为漏掉这步。
- 在
[mysqld]段添加(绝对路径!不能含变量、软链、中文或空格):audit_log_file = /var/log/mysql/audit.log audit_log_format = JSON audit_log_policy = ALL
- 确保 MySQL 进程用户(通常是
mysql)对父目录有写权限:sudo chown mysql:mysql /var/log/mysql,再sudo chmod 755 /var/log/mysql - SELinux 默认拦截:
sudo semanage fcontext -a -t mysqld_etc_t "/var/log/mysql(/.*)?",然后sudo restorecon -Rv /var/log/mysql
JSON 日志解析与权限静默失效排查
日志内容是单行 JSON,字段固定但无缩进,人眼难读——这不是 bug,是设计如此。空日志或日志不滚动,基本不是配置写错,而是权限或安全模块拦住了写入。
- 快速验证日志是否有效:
tail -f /var/log/mysql/audit.log | jq '.'(每行必须是合法 JSON) - 关键字段包括:
name(事件类型,如"connect"、"query")、status(0=成功)、query(SQL 文本,但 DDL 可能被截断) - 如果
ls -l /var/log/mysql/audit.log显示文件存在但大小为 0,优先检查:ls -Z /var/log/mysql(SELinux 上下文)、ps aux | grep mysqld(确认进程属主是mysql)、journalctl -u mysqld -n 50(看启动时是否有Could not open audit log file报错)
真正容易被忽略的是:audit_log 不记录参数绑定值,也不记录客户端发送前的预处理语句;它只记录 MySQL 协议层收到的原始字符串。如果你需要完整 SQL 文本(含实际参数),得结合 general_log 或代理层(如 ProxySQL)实现——但那会带来显著性能开销,生产环境慎用。

















