要查mongodb用户是否长期未用,必须依赖审计日志(需启动时配置)、profiling日志或业务侧配置归档;connectionstatus和system.users仅反映当前状态或静态存在,无法判断历史活跃情况。

直接查 system.users 不够,得结合登录审计日志
只看 db.getUsers() 或读 system.users 集合,只能知道“账号存在”,完全看不出它最近有没有人用。MongoDB 默认不记录用户登录行为,所以必须提前开启审计(auditLog)或启用访问日志(如 mongod 的 --logpath + verbose 日志级别),否则根本没数据可查。
- 审计日志需在启动时配置,例如:
--auditDestination file --auditFormat JSON --auditPath /var/log/mongodb/audit.log - 日志里关键字段是
"atype": "authenticate"和"user"字段,配合"localTime"才能判断活跃时间 - 如果没有审计,又没开慢查询日志(
db.setProfilingLevel(1)),那就只能靠人工确认:比如查该账号最后一次被用于连接字符串的部署记录、CI/CD 配置、应用配置文件等
db.runCommand({ connectionStatus: 1 }) 看不到历史登录,别白费劲
这个命令只返回当前连接的认证信息(比如 authInfo.loggedInUsers),不是历史记录。哪怕你刚用某个账号连进来,它也不会把过去一周的登录痕迹吐出来——它只反映此刻谁在线。
- 常见误操作:执行完
connectionStatus发现目标账号不在loggedInUsers里,就以为“这号早没人用了”,其实只是此刻没连上而已 - 真正要查“长期未用”,必须依赖外部日志或业务侧配置归档,MongoDB 自身不维护用户活跃时间戳
用 db.system.profile 辅助交叉验证(如果开了 profiling)
如果已启用 profiling(db.setProfilingLevel(1, { slowms: 100 })),可以反向查某账号是否触发过查询:对 db.system.profile 做聚合,过滤 user 字段和时间范围。
- 示例命令(查 admin 库下 user_reader 近 30 天是否有操作):
db.getSiblingDB("admin").system.profile.aggregate([ { $match: { "user": "user_reader", "ts": { $gt: new Date(Date.now() - 30*24*60*60*1000) } } }, { $group: { _id: null, count: { $sum: 1 } } } ]) - 注意:
system.profile只存查询动作,不存认证动作;且默认只保留最近 1MB 日志,容易被覆盖 - 如果 profile 里完全没该用户痕迹,再结合无审计日志、无配置引用,才比较有把握说它是“长期未用”
删之前务必确认认证数据库,db.dropUser() 是静默失败型操作
即使你确信某个账号半年没动过,执行 db.dropUser("legacy_app") 时,如果当前 shell 正处在 test 库,而该用户实际建在 admin 库,命令不会报错,但什么都不会发生。
- 必须先切库:
use admin,再执行db.dropUser("legacy_app") - 或者更稳妥:
db.getSiblingDB("admin").dropUser("legacy_app") - 删前用
db.getSiblingDB("admin").getUser("legacy_app")确认存在且db字段确实是"admin"
真正麻烦的是跨库同名用户——比如 myapp 和 logs 里都有 reporter,删错一个库的,另一个还在悄悄跑定时任务。











