真正能定位“管理员干了什么高危事”的只有server_audit插件或mysql 8.0.19+的audit_log,但需确认版本、插件状态、performance_schema启用、用户与事件类型配置四者齐备才有效。

直接用 general_log 记录所有语句不可行——它不区分用户、不标记权限等级、IO 压力大,且生产环境开启几小时就可能填满磁盘。真正能定位“管理员干了什么高危事”的,只有 server_audit 插件(Percona/MariaDB 开源方案)或 MySQL 8.0.19+ 的 audit_log,但后者默认不记录 SQL 文本、也不支持按用户过滤 DML/DDL,必须严格配对参数才有效。
确认你用的是可审计的插件和版本
先查清楚手头能不能用审计能力,别白配:
- 运行
SELECT VERSION();—— 如果低于8.0.19,audit_log社区版不可用,得切到server_audit - 运行
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME IN ('audit_log', 'server_audit');—— 返回空行说明插件没安装;状态不是ACTIVE就得查SHOW VARIABLES LIKE 'have_audit_log';,返回NO则硬加plugin_load_add会失败 -
server_audit.so文件必须放在plugin_dir下,且 MySQL 进程有读取权限;SELinux 或 AppArmor 可能拦截动态库加载,需检查系统日志
只捕获管理员的 DDL/DML:用 server_audit_events + server_audit_incl_users
server_audit 是目前唯一能在社区版中精准筛出“高权限用户执行了 DROP/ALTER/DELETE”的方案。它不靠权限位判断,而是靠用户名白名单 + 事件类型组合:
- 必须设
SET GLOBAL server_audit_events = 'QUERY_DDL,QUERY_DML,CONNECT';—— 漏掉CONNECT就看不到谁登录了,漏掉QUERY_DDL就捕不到INSTALL PLUGIN或SET GLOBAL这类 SUPER 级操作 - 用
server_audit_incl_users显式列出管理员账号,如SET GLOBAL server_audit_incl_users = 'root,dba_admin,backup_user';—— 注意不带主机名,'root'@'10.0.1.%'和'root'@'localhost'都会被匹配 -
server_audit_incl_users优先级高于server_audit_excl_users,所以别两个都设,容易互相覆盖 - 日志路径
server_audit_file_path必须是 MySQL 进程可写目录,建议用绝对路径,避免写进 datadir 导致备份混乱
audit_log 要生效,audit_log_policy 不能设成 ALL
很多人配完 audit_log_include_accounts = root 却发现日志里全是 PING 和 SELECT @@version,问题就出在策略上:
-
audit_log_policy = ALL会记录每条语句(包括健康检查),SQL 文本还不记录,纯属浪费 IO;必须设为COMMANDS才只记INSERT、ALTER_TABLE这类命令类型 -
audit_log_include_accounts只在audit_log_policy = ALL或COMMIT下生效 —— 但COMMIT只记录事务提交事件,不记录单条 DML,所以实际只能选ALL或COMMANDS,而后者才是合理选择 - 即使配对正确,
audit_log仍不记录完整 SQL,只记sql_command字段。想看到DELETE FROM users WHERE 1=1这种语句?得切回server_audit或临时开general_log - JSON 格式日志体积比文本大 2–3 倍,高频 DDL 场景下注意磁盘 I/O,别把日志和 binlog 放同一块盘
最容易被忽略的依赖项:performance_schema 必须启用
无论是 audit_log 还是 server_audit,底层都依赖 performance_schema 采集连接上下文(比如 client_host、thread_id)。如果它关着,日志里会出现大量空字段或 NULL 用户信息:
- 运行
SHOW VARIABLES LIKE 'performance_schema';,结果必须是ON;如果不是,需在my.cnf的[mysqld]段加上performance_schema = ON并重启 - 这个开关不支持动态开启,
SET GLOBAL performance_schema = ON;会报错 - 某些云数据库托管服务(如阿里云 RDS、腾讯云 CDB)默认关闭
performance_schema且不允许开启,这种情况下audit_log和server_audit的用户字段会失效,只能靠代理层(如 ProxySQL)补足
真正难的不是装插件,而是确保 performance_schema 启用、用户列表准确、事件类型不漏项、日志路径有权限——这四点缺一不可,否则日志看起来在跑,出事时却找不到人。











