mysql社区版不支持audit_log插件,仅企业版提供;执行install plugin会报错。需先用select version()确认版本含-commercial或enterprise字样,再检查plugin_dir下是否存在audit_log.so文件。

MySQL 社区版不自带 audit_log 插件,直接执行 INSTALL PLUGIN audit_log SONAME 'audit_log.so' 会报错——这个插件仅限 MySQL 企业版授权用户使用。
确认你用的是 MySQL 企业版还是社区版
误删数据后想查“谁删的”,第一件事不是配插件,而是看版本底子是否支持。社区版用户强行照搬企业版文档,90% 会卡在插件加载失败这一步。
- 执行
SELECT VERSION();,如果返回类似8.0.35-commercial或含enterprise字样,才可能有audit_log.so - 返回
8.0.35(无后缀)、5.7.44等纯数字版本,说明是社区版,audit_log插件根本不存在,文件路径下也找不到audit_log.so - 检查插件目录:
SHOW VARIABLES LIKE 'plugin_dir';,进该路径用ls -l | grep audit确认有没有audit_log.so——多数社区版服务器连这个文件都没有
社区版替代方案:优先选 MariaDB server_audit 插件
它开源、适配主流 MySQL 5.7/8.0、日志字段完整(含 user@host、SQL 原文、时间戳),且不依赖企业授权。但装错版本或漏设关键参数,日志照样为空。
- 下载对应版本的
server_audit.so:MySQL 8.0.35 就必须用 tag 标注mysql80的 release,别下mysql57的包 - 安装后必须设三件事:
SET GLOBAL server_audit_logging = ON;(开关)、SET GLOBAL server_audit_events = 'QUERY_DML,QUERY_DDL';(要记 DELETE/DROP)、SET GLOBAL server_audit_output_type = 'FILE';(否则默认 SYSLOG 可能丢日志) - 日志路径权限常被忽略:
server_audit_file_path指向的目录,必须由mysqld进程用户(通常是mysql)可写;SELinux 启用时,还需semanage fcontext -a -t mysqld_log_t "/path/to/audit(/.*)?"加上下文
配置后验证日志是否真在记录 DELETE
光看 SHOW PLUGINS 显示 ACTIVE 不够,得确认日志里真有 DELETE 行为。很多用户配完就以为万事大吉,结果误删后翻日志发现全是 CONNECT 记录,没一条 QUERY。
- 手动触发一次测试删除:
DELETE FROM users WHERE id = 9999;(确保该行存在,避免被优化掉) - 立刻查日志:
tail -n 20 /var/log/mysql/server_audit.log,找含"QUERY"和"DELETE"的行,关键字段应包括"user":"app_user@10.0.2.3"、"query":"DELETE FROM users WHERE id = 9999" - 如果只有
"CONNECT"没"QUERY",大概率是server_audit_events漏了QUERY,或者用了QUERY_DML却没开查询缓存导致 DML 被跳过——此时应设为'connect,query,table'更稳妥
真正防误删的关键不在插件,而在权限与流程
审计插件只负责“记下来”,不阻止误操作。线上库被 DELETE FROM users; 清空,往往不是因为没开审计,而是因为应用账号拥有 DROP/DELETE 权限,且没走审批流程。
- 禁止业务账号直接连生产库:用代理层(如 ProxySQL)或中间件统一鉴权,对
DELETE、DROP类语句做关键词拦截 - 最小权限原则:
GRANT SELECT,INSERT,UPDATE ON db.* TO 'app_user'@'%';,明确不给DELETE,删数据走专用运维账号 + 二次确认机制 - Binlog 必须开
binlog_format=ROW且binlog_rows_query_log_events=ON:即使审计日志损坏,还能靠mysqlbinlog还原具体哪条记录被谁删——这点比插件更底层、更可靠











