不能直接 rm -f 删除正在写入的 mongodb 审计日志文件,否则会导致日志写入失败、进程卡死或磁盘空间不释放;审计日志需显式启用且无内置轮转机制,必须通过 logrotate 配合 sighup 信号安全轮转,并严格验证路径、句柄占用及备份策略。

不能直接 rm -f 删除正在写入的 MongoDB 审计日志文件,否则会导致日志写入失败、进程卡死或磁盘空间不释放。
审计日志是否启用及路径确认
MongoDB 审计日志(auditLog)是独立于 systemLog 的模块,必须显式启用,且默认不开启。若你没在配置中设置 auditLog,那根本不存在“审计日志文件”——你可能误把普通运行日志当成了审计日志。
确认方式:检查 /etc/mongod.conf 或启动参数中是否存在类似以下配置:
auditLog: destination: file format: JSON path: /var/log/mongodb/audit.log
若无此段,audit.log 不存在,所谓“清理审计日志”就是误操作起点。
- 路径必须与
path值完全一致,常见错误是脚本里硬编码/var/log/mongodb/audit.log,但实际配置为/data/mongo/audit.json - 审计日志不支持
logRotate:1或SIGUSR1自动轮转——它没有内置滚动机制 - 如果启用了
destination: syslog,则日志由系统rsyslog管理,清理逻辑完全不同
审计日志安全轮转的唯一可行方式
MongoDB 审计日志本身不提供滚动能力,必须依赖外部工具(如 logrotate)配合原子重命名 + 信号通知,否则会丢失中间日志。
正确做法是:让 logrotate 切割文件后,向 MongoDB 进程发送 SIGHUP(不是 SIGUSR1),强制其重新打开日志文件句柄。MongoDB 2.6+ 支持该信号对审计日志生效。
-
logrotate配置中必须包含copytruncate或create+postrotate段,推荐后者 -
postrotate中执行:kill -SIGHUP $(cat /var/run/mongodb.pid)(确保 pid 文件路径准确) - 切勿使用
copytruncate处理高并发审计日志,存在极小概率丢日志(写入中被截断) - 审计日志格式为 JSON,切割后需确保每行是完整 JSON 对象,否则后续解析失败
手动清理前必须验证的三件事
即使确认了审计日志存在且路径正确,也不能直接删旧文件。先跑完这三步:
- 执行
lsof -p $(cat /var/run/mongodb.pid) | grep audit—— 若输出显示audit.log被进程占用(TYPE 为 REG,FD 为数字),说明文件仍被打开,直接rm只是 unlink,磁盘空间不会释放 - 检查
df -h和du -sh /var/log/mongodb/audit.log*是否差异巨大——若du小但df显示磁盘满,大概率是文件被删但句柄未释放,此时必须重启或发SIGHUP - 确认备份策略:审计日志一旦删除无法恢复,生产环境必须先
gzip归档再删,且保留至少 90 天(合规常见要求)
定时清理脚本的关键陷阱
网上流传的“find ... -mtime +30 -delete”脚本在审计日志场景下极易出事,因为:
- 审计日志文件名无时间戳(如
audit.log.2026-08-01),find -mtime依赖的是文件修改时间,而logrotate后的归档文件 mtime 是切割时刻,不是日志内容时间 - 若用
find /var/log/mongodb -name "audit.log.*" -mtime +30,可能误删刚切割但内容含敏感操作的文件 - 正确做法是:用
logrotate的rotate 90+dateext生成带日期后缀的文件,再用find ... -name "audit.log.*" -regex ".*audit\.log\.[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}" -mtime +90 - 所有清理命令必须加
echo预演,例如:find ... -print先看命中的文件列表,确认无误再加-delete
最易被忽略的一点:审计日志的 path 配置可能指向一个符号链接,find 默认不跟随链接,导致清理失效——得加 -L 参数,但又可能引发跨文件系统误删,必须提前 readlink -f 解析真实路径。











