mysql 8.0.19+ 社区版可用 audit_log 插件,但默认不记录 sql 文本且不支持按用户粒度过滤 dml/ddl;需组合 audit_log_include_accounts 与 audit_log_policy = commands 才能精准捕获高权限用户的 insert/update/delete/drop/alter 操作,否则应选用 server_audit 插件。

audit_log 插件在 MySQL 8.0.19+ 社区版中可用,但默认不记录 SQL 文本,也不支持按用户粒度过滤 DML/DDL —— 想精准捕获“高权限用户”的 INSERT/UPDATE/DELETE 和 DROP/ALTER 等操作,必须组合策略配置与外部约束,不能只靠 audit_log_policy = ALL。
确认你用的是可审计的版本和插件状态
先运行:SELECT VERSION(); 和 SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'audit_log';。如果版本低于 8.0.19 或返回空行,audit_log 不可用,得换 server_audit(MariaDB 审计插件);若状态不是 ACTIVE,说明插件未加载成功或未编译支持——此时查 SHOW VARIABLES LIKE 'have_audit_log';,返回 NO 就别硬配 plugin_load_add,重启只会报 Can't open shared library。
只审计高权限用户:用 audit_log_include_accounts 而非账号密码白名单
audit_log_include_accounts 是唯一能按账号过滤的参数,它接受逗号分隔的用户名列表(不带主机名),例如:root,dba_admin,backup_user。注意:
- 它匹配的是
USER()返回值,即username@host中的 username 部分,所以'admin'@'10.0.1.%'和'admin'@'localhost'都会被audit_log_include_accounts = admin捕获 - 不能写成
'root'@'%',否则加载失败;也不能用正则或通配符 - 该参数只在
audit_log_policy = ALL或COMMIT下生效;设为VALIDATE时无效 - 如果用户是通过代理或中间件连接(如 ProxySQL),实际
USER()可能是代理账号,需确认链路末端身份
audit_log_policy = COMMANDS 才真正聚焦 DDL/DML,不是 ALL
audit_log_policy = ALL 会记录每条 SELECT、甚至 PING,IO 压力大且淹没关键事件;而 COMMANDS 仅记录明确的语句执行事件(QUERY 类型),配合 audit_log_include_accounts 才能筛出高权限用户的操作行为。但要注意:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
-
COMMANDS不记录连接/断开事件,所以登录暴破类行为漏掉——如需,得额外开connect和disconnect,但只能用server_audit实现 - 它仍不记录 SQL 文本,只记
sql_command字段(如INSERT、ALTER_TABLE),无法知道改了哪行数据;想看完整语句,得切到server_audit或启用general_log(仅临时) -
audit_log_format = JSON时,sql_command字段在 8.0.23+ 才稳定存在,旧版本可能为空,务必验证日志样例
社区版用户绕过限制的实操底线:用 server_audit 补 audit_log 缺失能力
如果你用的是 MySQL 社区版(尤其 8.0.18 及更早),或需要记录 SQL 文本、按 IP 过滤、捕获存储过程内动态 SQL,server_audit 是目前最兼容的选择。安装后关键配置项有:
-
server_audit_events = connect,query_ddl,query_dml,table:其中query_ddl涵盖CREATE/DROP/ALTER,query_dml涵盖INSERT/UPDATE/DELETE(不含SELECT) -
server_audit_incl_users = root,dba_admin:精确匹配用户名,大小写敏感 -
server_audit_output_type = file且server_audit_file_path必须是绝对路径,MySQL 用户对该路径有写权限(常见坑:/var/log/mysql目录不存在或属主不对) -
server_audit_logging = ON必须显式开启,否则配置全无效
日志里会直接出现类似 20260701 14:22:33,localhost,root,127.0.0.1,test,QUERY,test,'UPDATE users SET status=1 WHERE id=123',0 的条目——SQL 文本在第 8 字段,解析成本低,但文件体积比 audit_log JSON 大 2~3 倍。
真正难处理的不是怎么开插件,而是日志轮转策略没配好导致磁盘打满,或者把 audit_log_file 或 server_audit_file_path 写成相对路径,MySQL 启动时静默失败,你以为开了其实没写入任何内容。










