MySQL自身不支持审计日志自动轮转,Percona插件通过audit_log_rotate_on_size和audit_log_rotations实现原生轮转;生产环境须叠加logrotate+postrotate脚本完成压缩、校验、异地备份,严防轮转窗口丢失日志。

审计日志文件直接轮转归档
MySQL 自身不提供审计日志的自动轮转(audit_log_file 是静态路径),但 Percona Audit Log 插件支持 audit_log_rotate_on_size 和 audit_log_rotations 两个关键参数。启用后,当日志文件达到设定大小(如 100MB),插件会自动重命名当前文件(加数字后缀)、创建新日志,并保留指定数量的历史轮转文件。
示例配置(写入 my.cnf 的 [mysqld] 段):
audit_log_policy = ALL audit_log_file = /var/log/mysql/audit.log audit_log_rotate_on_size = 104857600 audit_log_rotations = 7
注意:audit_log_rotate_on_size 单位是字节,104857600 = 100MB;audit_log_rotations = 7 表示最多保留 7 个旧日志(audit.log.0 到 audit.log.6)。该机制不依赖外部工具,但轮转触发后需立刻同步备份,否则旧文件可能被下一次轮转覆盖。
用 logrotate 配合 postrotate 脚本做异地备份
仅靠插件轮转不够可靠:它不压缩、不加密、不传远端,且轮转瞬间存在微小窗口丢失日志的风险。生产环境应叠加 logrotate 做二次归档,关键是利用 postrotate 执行备份动作——在 MySQL 重打开日志文件后,立即将刚轮转出的旧文件压缩并推送至备份服务器。
示例 /etc/logrotate.d/mysql-audit:
/var/log/mysql/audit.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 mysql mysql
sharedscripts
postrotate
# 确保 MySQL 已完成日志重开
sleep 1
# 查找最新生成的 .gz 文件(即刚轮转并压缩完的那个)
LATEST=$(ls -t /var/log/mysql/audit.log.*.gz 2>/dev/null | head -n1)
if [ -n "$LATEST" ]; then
# 推送到备份服务器(需提前配置 SSH 免密)
scp "$LATEST" backup@192.168.10.50:/backup/mysql/audit/
# 同时计算校验和并记录时间戳
sha256sum "$LATEST" >> /backup/mysql/audit/sha256sums.log
fi
endscript
}
要点:sharedscripts 确保 postrotate 只执行一次;delaycompress 让压缩延后到下次轮转,避免脚本读不到刚生成的 .gz;sleep 1 是给 MySQL 留出 flush 日志的时间,实测低于 500ms 时偶发失败。
审计日志表化存储 + mysqldump 定期导出
如果使用的是 MariaDB Audit Plugin 或 MySQL Enterprise Audit Plugin(非 Percona),它们支持将审计事件写入系统表(如 mysql.audit_log)。这种模式天然适合用 mysqldump 归档,但要注意三点:
- 表结构随插件版本变化,导出前先运行
SHOW CREATE TABLE mysql.audit_log留存 DDL - 该表默认无主键、无索引,大流量下 INSERT 性能差,建议每天凌晨低峰期执行
mysqldump --no-create-info --where "event_time audit_$(date -d 'yesterday' +\%F).sql - 导出后立即
DELETE FROM mysql.audit_log WHERE event_time ,避免审计表无限膨胀拖慢整个实例
为什么不能只依赖 binlog 做审计归档
binlog 记录的是数据变更(DML/DDL),而审计日志记录的是“谁、何时、从哪、执行了什么语句”,包含登录失败、权限拒绝、SELECT 查询等 binlog 完全不捕获的行为。更关键的是:binlog 默认不记录客户端 IP、操作系统用户、应用名等上下文字段,也无法区分 root@localhost 和 root@10.0.1.5 的操作来源。把审计当安全合规证据时,必须保留原始审计日志文件或表,binlog 只能作为补充,不能替代。
真正容易被忽略的点是:审计日志轮转与备份之间的时间窗口。无论用插件原生轮转还是 logrotate,都必须验证备份动作是否 100% 成功——比如在 postrotate 里加 set -e 并检查 scp 返回码,否则某天磁盘满或网络抖动导致备份静默失败,你不会收到任何告警,直到审计追溯时发现缺了三天日志。











