启用 MongoDB 副本集的 system.profile 集合需在 admin 数据库的主节点执行 db.setProfilingLevel(1, { slowms: 100 }),配置需通过启动参数或 mongod.conf 持久化,否则重启失效;日志仅存于主节点且为 capped collection,默认 1MB,不复制、不同步。

如何启用 MongoDB 副本集的 system.profile 集合
副本集默认不开启性能分析,system.profile 是一个 capped collection,必须手动启用才能记录慢查询。它只存在于当前数据库(如 test),但通常建议在 admin 数据库下启用,以便统一监控所有库的操作。
连接到主节点后执行:
use admin
db.setProfilingLevel(1, { slowms: 100 })
注意:setProfilingLevel 只对当前数据库生效;在 admin 库执行,才能让 profile 记录覆盖整个实例(包括其他 db 的操作)。
-
1表示记录慢查询(slowms以上);2表示记录所有操作(仅调试用,禁止在生产环境长期开启) - 副本集里该命令**必须在主节点执行**,从节点会拒绝写入
system.profile - 如果提示
"not master",说明连错了节点,先用rs.isMaster().ismaster确认身份
为什么改了 slowms 却没看到新日志
常见原因是配置未持久化,或 profile 级别被后续命令覆盖。MongoDB 不会自动将 setProfilingLevel 写入配置文件,重启后失效。
解决方法:
- 在启动参数中加入
--profile 1 --slowms 50,或在配置文件mongod.conf中添加:
operationProfiling: mode: slowOp slowOpThresholdMs: 50
- 检查当前生效值:
db.getProfilingStatus()—— 返回{ "was": 1, "slowms": 100 }才算真正生效 - 如果返回
"was": 0,说明 profiling 被关了,可能是被脚本/运维工具重置过
怎么查 system.profile 里的慢查询(含真实时间、锁耗时、执行计划)
直接查 system.profile 能看到原始事件,但字段多、嵌套深,重点看这几个字段:
-
ts:操作开始时间(ISODate) -
millis:总耗时(毫秒),即是否触发 slowms 的依据 -
ns:命名空间(如myapp.users) -
op:操作类型(query、update、command) -
planSummary:执行计划摘要(如COLLSCAN或IXSCAN) -
lockStats.timeAcquiringMicros:锁等待微秒数(高并发下关键指标)
示例:查最近 10 条超过 200ms 的查询
use admin
db.system.profile.find({ millis: { $gt: 200 } })
.sort({ ts: -1 })
.limit(10)
.pretty()
注意:system.profile 是 capped collection,默认大小 1MB,旧日志会被自动覆盖。如需保留更久,可在创建时指定 size,但需提前停服务并用 db.createCollection 手动建。
副本集里 profile 日志只存在主节点,从节点查不到
这是设计使然:system.profile 不复制,也不同步。从节点不会生成自己的 profile 日志,即使你连上去执行 setProfilingLevel,也会报错或静默失败。
所以监控必须:
- 只连主节点查日志(可用
rs.primary获取当前主) - 不要依赖从节点做慢查询归集
- 如果用了 mongos(分片集群),profile 也只在各 shard 的主上独立存在,需分别采集
另外,system.profile 不记录连接、认证、网络超时类问题,这类得靠 mongod 的 log 文件 + logLevel: 1 或更高来捕获。

















