mysql 8.0.19+ 自带 audit_log 插件但默认禁用,仅记录元数据(用户、ip、时间等),不记录 sql 文本;需确认版本≥8.0.19、插件已启用并配置 audit_log_policy=all 及 audit_log_file 等参数,且注意其无法捕获 mysqldump、动态 sql 和复制操作。

MySQL 社区版 8.0.19+ 自带 audit_log 插件,但默认不启用,且它只记录操作元数据(用户、IP、时间、事件类型、状态码),不记录 SQL 语句文本本身。想“记录所有操作”,必须先明确:你到底要记录什么?是行为轨迹,还是可回放的完整 SQL?
确认 MySQL 版本与插件可用性
低于 8.0.19 的社区版没有内置 audit_log.so,硬装会报 ERROR 1126 (HY000): Can't open shared library 'audit_log.so'。
- 执行
SELECT VERSION();确认版本 ≥ 8.0.19 - 执行
SHOW VARIABLES LIKE 'have_audit_log';,返回YES才表示编译时启用了该插件 - 执行
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'audit_log';,无结果或状态为DISABLED就别继续了——得升级或换方案
加载插件并设置 audit_log_policy = 'ALL'
audit_log_policy 是运行时开关,SET GLOBAL 只临时生效;要持久化,必须写进配置文件并重启。
- 用有
SYSTEM_VARIABLES_ADMIN和SYSTEM_USER权限的账户执行:INSTALL PLUGIN audit_log SONAME 'audit_log.so'; - 立即启用全量审计:
SET GLOBAL audit_log_policy = 'ALL';(可选值只有ALL、LOGINS、QUERIES;VALIDATE会直接报错) -
ALL仍不记录mysqldump、存储过程内动态 SQL、复制线程操作——这些走内部协议,不触发 QUERY 事件
配置文件中指定日志路径与格式
audit_log_file 必须在启动前通过配置文件指定,SET GLOBAL audit_log_file = '/path' 无效。常见失败不是配错路径,而是权限断层。
- 编辑
my.cnf,在[mysqld]下添加:
plugin_load_add = audit_log.so audit_log = FORCE_PLUS_PERMANENT audit_log_format = JSON audit_log_policy = ALL audit_log_file = /var/lib/mysql/audit.log
audit_log_format = JSON 最常用,但注意:每行是一个独立 JSON 对象,不是标准 JSON 数组,不能直接 cat audit.log | jq .;需逐行解析(如 Python 中用 json.loads(line))/var/lib/mysql/)必须由 mysql 用户可写:chown mysql:mysql /var/lib/mysql
NEWLINE 大 30%~50%,建议加 audit_log_rotate_on_size = 1000000 防止撑爆磁盘为什么你总以为“没记录到”?
这不是配置失败,而是对 audit_log 能力的误判。它天生不记录 SQL 文本内容(比如 UPDATE users SET name='x' WHERE id=1),也不捕获以下三类操作:
-
mysqldump导出时的 SELECT 流量 - 存储过程中用
PREPARE/EXECUTE执行的动态 SQL - 主从复制线程在 IO/SQL 线程里做的变更
如果业务强依赖 SQL 文本审计,audit_log 不是答案——该换用 Percona Server 的 server_audit,或开启 general_log(但性能代价极大),或改用 Binlog + 解析方案。别在 audit_log 上反复调参试图“绕过限制”。











