不能,general_log因性能损耗大、不记录用户/ip/执行结果且日志冗余,无法满足审计对可追溯性的基本要求;推荐使用audit_log插件、server_audit或mysql-audit等专用方案。

MySQL 自带的 general_log 能不能当审计日志用
不能,或者至少不推荐。开启 general_log 会记录所有语句(包括 SELECT),性能损耗大、日志体积爆炸,且不区分用户、无执行结果、不记录失败操作——审计最关心的“谁在什么时候干了什么”信息残缺。
实操建议:
- 仅临时排查问题时打开:
SET GLOBAL general_log = ON;,并指定输出到表:SET GLOBAL log_output = 'TABLE';,避免写文件影响 I/O - 生产环境长期开启前,必须评估 QPS 和磁盘空间,且需搭配定时清理(如每天 truncate
mysql.general_log) - 它不记录连接来源 IP、认证状态、执行是否成功,无法满足等保或内部审计对“可追溯性”的基本要求
MySQL 8.0+ 审计插件 audit_log 的启用方式
MySQL 官方提供的 audit_log 插件(需企业版)或社区兼容方案(如 Percona Server 的 audit_log)是更合适的起点。但注意:Oracle MySQL 社区版默认不带该插件,需确认版本与分发渠道。
启用前检查:
- 运行
SHOW PLUGINS;查看是否有audit_log行,状态为ACTIVE - 若无,社区版可考虑
mysql-audit(McAfee 开源插件),需编译安装;Percona Server 用户直接配置audit_log=ON - 关键配置项(写入
my.cnf):audit_log=FORCE_PLUS_PERMANENT(防被动态关闭)、audit_log_format=JSON(结构化易解析)、audit_log_policy=ALL或LOGINS(按需选)
重启后日志默认写入 /var/lib/mysql/audit.log,每条记录含 timestamp、user、host、command_class、sql_text(敏感内容可能被截断或脱敏)
替代方案:用 MySQL 5.7+ 的 server_audit 插件(MariaDB 兼容)
如果用的是 MariaDB 或已部署 server_audit(如来自 libserver_audit.so),它比原生 audit_log 更轻量、社区支持更好,且开源免费。
配置要点:
- 确认插件存在:
INSTALL PLUGIN server_audit SONAME 'server_audit.so'; - 常用参数(写入
my.cnf):server_audit_logging=ON、server_audit_events='connect,query_ddl,query_dml'(避免记录大量SELECT)、server_audit_file_path='/var/log/mysql/server_audit.log' - 注意
server_audit_syslog_priority若设为LOG_INFO,日志会进/var/log/messages,需配合 rsyslog 做归档 - 该插件不记录 SQL 参数值(如
WHERE id = ?中的 ?),规避敏感数据落盘风险,但也意味着无法还原完整语句
审计日志权限与落盘安全必须做的三件事
日志本身若可被篡改或删除,审计就失去意义。权限控制和存储策略比“开没开”更重要。
必须检查:
-
audit.log文件属主必须是mysql,权限严格设为640,所在目录禁止其他用户写入;否则攻击者提权后可清空日志 - 使用
logrotate切割时,务必加create 640 mysql mysql,防止新文件权限错误 - 日志应同步到独立服务器(如用
rsyslog + RELP),本地只保留 7 天;避免数据库崩了日志也一起丢
真正难的不是配置开关,而是定义清楚“哪些操作必须留痕”(比如 DROP TABLE、GRANT、高危 UPDATE)、如何和 SIEM 系统对接、以及定期验证日志不可篡改——这些往往被忽略,却直接决定审计是否有效。










