MongoDB的企业版提供审计功能,可以记录认证、授权、DDL操作等各类安全事件,满足等保和合规要求。但审计是把双刃剑,一旦审计事件的过滤范围配置过宽,系统会在高并发场景下疯狂写入审计记录,触发故障码2100,日志文件以肉眼可见的速度膨胀,最终把磁盘写满,导致整个实例不可用。这篇文章就把这个问题掰开揉碎讲清楚。

故障码2100到底是怎么产生的
先说结论,2100并不是MongoDB内核抛出的严重错误码,而更多是运维层面约定的一个告警编号,用于标识审计日志写入量异常、日志体积超出阈值的场景。当mongod开启了auditLog之后,每一个符合过滤条件的操作都会生成一条审计记录,记录内容包括操作时间、连接ID、用户、数据库名、操作类型、参数文档等字段。看起来每条记录不大,但在每秒上万次操作的集群里,审计写入量可能达到每秒几十MB甚至上百MB。
问题在于审计写入默认是同步追加到本地文件的。如果auditLog的destination配置为file,mongod会通过一个后台线程将审计事件写入磁盘。写入速度跟不上事件产生速度时,事件会在内存队列中堆积。更糟糕的是,某些部署模式下审计写入失败会直接导致操作被拒绝,也就是说审计日志膨胀不只是占磁盘,还可能拖慢甚至阻断正常业务请求。
还有一个容易被忽视的细节:审计事件里会包含操作的完整参数文档。比如一次update操作,审计记录里会带着完整的更新条件和更新内容。如果业务上存在批量更新大文档的场景,单条审计记录就可能达到数百KB,这种放大效应会让日志膨胀速度远超预期。
为什么审计过滤器没有收紧是罪魁祸首
审计功能的filter参数决定了哪些事件会被记录。很多团队初次启用审计时,为了保证"看得全",直接留空filter或者写一个几乎不过滤的条件,结果就是把所有操作全部记录下来。实际上,合规审计真正关心的是安全相关事件,而不是普通的业务读写。
一个合理的做法是只审计认证失败、授权变更、用户管理等高危事件。下面是一个典型的过滤配置示例:
// 只记录认证失败和用户管理操作,大幅减少日志量
auditLog: {
destination: file,
format: JSON,
path: /var/log/mongodb/audit.json,
filter: {
$or: [
{ atype: "authCheck", "param.command": { $in: [ "createUser", "dropUser", "grantRolesToUser", "revokeRolesFromUser" ] } },
{ atype: { $in: [ "authenticate", "logout" ] }, "result": 18 }
]
}
}
这段配置的核心思路是收窄审计面。result为18对应认证失败错误码,只记录失败认证可以有效捕捉暴力破解尝试,同时不会为每次正常登录都写日志。仅这一项调整,日志写入量通常能下降一个数量级以上。
另外,format的选择也有讲究。JSON格式可读性好但体积大,BSON格式体积小约30%到50%,适合长期保留和集中传输。如果下游有统一的日志解析平台,建议本地用BSON落盘,由采集端解析后再入库存JSON,兼顾体积和可读性。
日志滚动与容量治理方案
即使收紧了过滤器,审计日志仍然会持续增长,滚动切割策略必不可少。MongoDB本身支持通过logRotate命令手动触发日志轮转,配合logrotate工具可以实现按天或按大小切割:
# /etc/logrotate.d/mongodb-audit 配置示例
/var/log/mongodb/audit.json {
daily
rotate 14
maxsize 2G
compress
delaycompress
missingok
notifempty
postrotate
# 通知mongod重新打开日志文件句柄
mongo --quiet --eval "db.adminCommand({ logRotate: 1 })"
endscript
}
这套配置的含义是每天切割一次,最多保留14份,超过2GB也强制切割,旧文件压缩存储。logRotate命令会让mongod关闭当前日志文件并重新打开,避免切割后继续写入旧文件句柄导致空间无法释放。这里有个经典的坑:用mv直接移动正在写入的日志文件,磁盘空间并不会释放,因为文件句柄还被进程持有,必须配合logRotate或者copytruncate方式处理。
除了本地滚动,更架构化的方案是把审计事件直接发送到Syslog服务器,即把destination配置为syslog,本地不落盘。这样审计日志由专门的日志平台统一管理,天然具备滚动、压缩、归档能力,也不占用数据库服务器的磁盘。对于已经采用ELK或类似体系的企业,这是更推荐的做法。
监控与容量评估,避免问题复发
解决一次故障不难,难的是防住下一次。建议对审计日志目录做独立监控,两个指标必须覆盖:磁盘使用率和日志写入速率。磁盘使用率超过70%告警,写入速率异常放大(比如环比增长5倍)也要告警,后者往往意味着有异常操作正在发生,本身就是一个安全信号。
容量评估可以用一个简单公式估算:日均审计量约等于每秒事件数乘以单条平均大小乘以86400秒。上线前可以先用宽松的过滤器试运行一天,统计实际产生量,再据此反推合理的过滤规则和保留周期。等保等合规要求通常要求审计记录保留6个月,那么规划磁盘时就要按切割文件压缩后的总体积乘以180天来预留空间,或者直接规划归档到对象存储。
最后提醒一点,审计配置的变更要走变更管理流程。收紧过滤器虽然能解决2100告警,但如果擅自去掉了合规要求的事件类型,安全审计就形同虚设。正确的顺序是:先与安全团队确认必需的审计范围,再在必需范围内优化过滤条件、格式和滚动策略,让安全与性能取得平衡。做到这几点,故障码2100基本就不会再找上门了。