system.profile默认不启用,仅在profiling开启后创建,且必须通过admin库授权并连接真实mongod节点才能访问;atlas或mongos环境下不可用。

system.profile 表默认不启用,新建用户无权访问
因为 system.profile 是数据库分析器(profiler)启用后自动创建的特殊集合,它不属于普通数据库对象,也不受常规 read 或 readWrite 角色覆盖。即使你给用户授予了 dbAdmin 或 root 角色,只要分析器没开启,该集合就不存在;就算存在,也必须显式授权才能读取。
必须用 db.getSiblingDB("admin").runCommand() 在 admin 库下操作
system.profile 位于具体数据库(如 mydb)下,但它的读写权限控制逻辑和普通集合不同:MongoDB 要求对 profile 集合的访问必须通过 admin 数据库发起命令,且用户需在 admin 库拥有对应权限。常见错误是直接在业务库执行 db.system.profile.find() —— 这会因权限校验失败而报 not authorized on mydb to execute command { find: "system.profile" }。
- 正确做法是切换到
admin库再查:db.getSiblingDB("admin").runCommand({ listDatabases: 1 })可确认权限是否生效 - 若要允许某用户读
mydb.system.profile,需在admin库为其添加角色:db.getSiblingDB("admin").grantRolesToUser("myuser", [{ role: "read", db: "mydb" }]) - 注意:仅
read不够,必须确保该角色作用域明确指向mydb,不能只授read给admin库
profile 级别为 0 时 system.profile 根本不存在
很多用户误以为建完用户就能立刻查 system.profile,但其实这个集合只在分析器启用后才被创建。如果当前 db.getProfilingLevel() 返回 0,说明分析器已禁用,system.profile 为空或根本未初始化 —— 此时任何读操作都会失败,不是权限问题,而是集合不存在。
- 启用方法:
db.setProfilingLevel(2)(记录所有操作)或db.setProfilingLevel(1, { slowms: 100 })(只记慢查询) - 执行后检查:
db.getCollectionNames().includes("system.profile")应返回true - 切勿在生产环境长期开启
level 2,它会显著拖慢性能并暴露敏感查询文本
Atlas 和 mongos 实例不支持直接读取 system.profile
如果你用的是 MongoDB Atlas 或连接的是 mongos 路由节点,system.profile 的行为完全不同:mongos 没有本地存储,无法维护 profile 集合;Atlas 则完全屏蔽该集合的直接访问,改用其内置性能监控面板替代。此时无论怎么授权、怎么切换库,db.system.profile.find() 都会报错 command not supported 或 no such collection。
- Atlas 用户应使用 Atlas UI 的 Performance Advisor 或 Query Profiler 功能
- 分片集群中 profiling 必须在每个 shard 的
mongod实例上单独启用,mongos层无法聚合或代理该集合读取 - 验证方式:
db.runCommand({ connectionStatus: 1 }).authInfo.authenticatedUsers看当前连接是否落在真实mongod节点上
system.profile 是个“条件触发型”集合——它依赖分析器状态、依赖连接目标类型、还依赖权限作用域的精确匹配。三个条件缺一不可。











