MySQL全量SQL审计首选general_log(轻量临时)、audit_log插件(权限操作)或server_audit插件(Percona/MariaDB),需关注日志目标、性能影响、轮转机制、权限控制与时区一致性。

MySQL 开启 general_log 记录所有 SQL 执行语句
直接开 general_log 是最轻量的全量审计方式,适合临时排查或低流量环境。它会把客户端发来的每条语句(含连接、断开)原样记入文件或表,但不记录执行结果、权限校验过程或内部操作。
- 运行时开启:
SET GLOBAL general_log = ON;,需 SUPER 权限;关闭同理设为OFF - 日志目标选文件更稳妥:
SET GLOBAL log_output = 'FILE';,避免写表引发锁或性能抖动;默认路径是datadir下的hostname.log,可通过general_log_file变量指定 - 注意:开启后日志体积增长极快,尤其有频繁查询或批量导入时;生产环境不建议长期开启,且必须确保磁盘空间和轮转机制(MySQL 不自动轮转,得靠外部脚本或 logrotate)
- 权限限制:普通用户查不到
general_log表内容,即使日志输出到表(mysql.general_log),该表默认只对 root 或有SELECT权限的用户可见
使用 audit_log 插件做权限级操作审计(MySQL 5.7+ 官方企业版 / MySQL 8.0 社区版)
audit_log 插件比 general_log 更聚焦“谁在什么时间做了什么权限相关动作”,比如登录失败、DDL 变更、用户权限修改等,不记录 SELECT/INSERT 等业务语句本身,但能标记出触发这些语句的用户与连接上下文。
- 加载插件:
INSTALL PLUGIN audit_log SONAME 'audit_log.so';(Linux)或'audit_log.dll'(Windows);确认已启用:SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'audit_log'; - 关键配置项:
audit_log_policy控制记录粒度(ALL/LOGINS/QUERIES),audit_log_format推荐用JSON(便于解析),audit_log_file指定路径(务必确保 MySQL 进程有写权限) - 常见坑:插件加载失败常因路径不对或 SELinux/AppArmor 阻止动态库加载;日志文件被清空后插件不会自动重建,需重启 mysqld 或手动 touch + chown
- 性能影响较小,但 JSON 格式日志体积比纯文本大 2–3 倍,高频 DDL 场景下仍需关注 I/O 压力
Percona Server 或 MariaDB 用户:用 server_audit 插件替代
如果你用的是 Percona Server(5.7/8.0)或 MariaDB(10.1+),server_audit 是更成熟的选择。它支持细粒度过滤(如排除 health check 查询)、异步写日志、自动轮转,且社区版完全免费。
- 启用方式:
INSTALL PLUGIN server_audit SONAME 'server_audit.so';,然后设置server_audit_logging=ON、server_audit_events='CONNECT,QUERY,TABLE'等 - 过滤敏感语句:通过
server_audit_excl_users排除监控账号,用server_audit_incl_users只审计特定账号,避免日志爆炸 - 注意:MariaDB 10.4+ 默认禁用
QUERY类型审计(因性能),需显式开启;Percona 的server_audit不记录参数化查询中的实际值,只记语句模板,这点比general_log更安全 - 日志轮转依赖
server_audit_file_rotate_now=ON(手动触发)或配置server_audit_file_rotations和server_audit_file_rotate_size
审计日志落地后的基本处理要点
日志写出来只是第一步,没人看等于没开。真正起作用的前提是能快速定位、过滤、归档。
- 别直接 tail -f 生产日志文件:MySQL 写日志时可能缓存或延迟刷盘,实时性有限;且大文件 grep 极慢,优先考虑用
awk或jq(针对 JSON)做字段提取 - 时间戳统一问题:
general_log用系统时间,audit_log和server_audit用 MySQL 服务器时间,若 DB 与应用服务器时区不一致,排查时容易错乱 - 敏感信息脱敏:日志里可能含密码、手机号等,不能直接导出分析;可在写入前用中间件(如 fluentd filter)或 MySQL 8.0+ 的
log_error_verbosity+ 自定义 UDF 实现简单掩码,但需权衡性能 - 存储周期要明确:保留 7 天还是 90 天?是否上 ELK?这些决定应早于开启审计,否则很快面临磁盘打满或合规审查时找不到对应时段日志


















