mongodb自身不审计mongoexport操作,因其直连mongod批量拉取bson并本地转换,不触发profile、explain或服务端查询统计;仅企业版auditlog可记录authenticate和find事件,但无法还原具体导出数据。

MongoDB 本身不记录谁导出了哪条数据,mongoexport 是客户端工具,操作完全绕过服务端审计日志;真正能抓到“谁读了什么”的只有慢查询日志(profile)或网络层抓包,但代价高、不可靠。
为什么 mongoexport 不在数据库审计范围内
它不是通过 db.collection.find() 发起的查询,而是直连 mongod,用 cursor 批量拉取 BSON 数据后本地转成 JSON/CSV。整个过程:
- 不触发任何
system.profile记录(即使profile级别设为 2) - 不走
explain()或查询计划器,serverStatus 里也看不到对应 query 统计 - 连接日志(
net.conn)只记 IP 和端口,不记具体命令或参数
mongostat 和 mongotop 能看出导出行为吗
不能直接识别“这是导出”,但可间接观察异常读负载:
-
mongostat中query+getmore显著升高,且qr(读队列)持续 >0,说明有大量游标在拉数据 -
mongotop会显示某集合read时间暴增(比如从几 ms 跳到几百 ms),尤其当ns对应的是用户常导出的集合(如users、orders) - 注意:
mongotop的total是累计耗时,不是单次延迟;read高 ≠ 查询慢,可能是批量扫描导致
真正可行的监控点:启用 auditLog + 抓网络流量
MongoDB 社区版不支持审计日志,必须用企业版或 4.2+ 付费功能;若已启用,关键字段是:
-
"atype": "authenticate"→ 记录谁连上了 -
"atype": "find"+"ns": "db.collection"→ 记录实际查询动作(但mongoexport默认不带--query,就是全表扫,所以这里只会看到大量find请求) - 问题在于:auditLog 不记录 cursor 的
getMore请求细节,无法还原“导出哪几条”
更务实的做法是网络层镜像流量,用 tcpdump 抓 mongod 端口(默认 27017)的 BSON 包,再用 mongodump 的 BSON 解析逻辑反推原始查询条件——但这需要自研解析器,生产环境极少落地。
容易被忽略的性能陷阱:cursor 超时与内存压力
导出操作本质是长生命周期 cursor,影响比普通查询更隐蔽:
- 默认 cursor timeout 是 10 分钟(
maxTimeMS不控制这个),大集合导出中途断连会导致服务端残留游标,占用内存 -
mongostat的used(WiredTiger 缓存使用率)可能缓慢上升,因为游标缓存未及时释放 - 如果同时跑多个
mongoexport,conn数飙升,qr/qw队列堆积,其他业务查询开始超时 - 验证方式:
db.currentOp({secs_running: {$gt: 60}})查看运行超 1 分钟的操作,重点看"secs_running"和"cursor"字段
真正难防的是没权限意识的运维人员本地执行 mongoexport —— 它不走 RBAC 权限校验(只要连接认证通过),连 read 角色都不需要。能做的只有网络白名单 + 代理层日志,而不是指望 MongoDB 自身审计。











