事务本身不导致slowms日志增多,真正原因是事务内单条操作耗时超阈值;profiler记录的是事务中每条实际操作而非事务整体,需通过system.profile的ns、planSummary、docsExamined等字段定位慢操作根源。

事务本身不会直接导致 slowms 记录变多,真正触发大量慢日志的是事务中单条操作(如 find、updateOne)的执行耗时超过了当前 slowms 阈值。调高阈值只是掩盖问题,关键得先确认是不是事务内某步卡住了。
为什么开启事务后system.profile里突然全是慢日志
事务在 MongoDB 中是原子性执行的,但 profiler 不记录“事务开始/结束”,而是记录事务内每一条实际操作(op: "update"、op: "command" 等)。如果事务里包含一个没走索引的 find,或一次批量 insert 写入了上万文档,它就会单独被记为一条 millis > slowms 的日志。
- 常见错误现象:
db.getProfilingStatus()返回{"was": 1, "slowms": 100},但db.system.profile.find({ op: "command" }).count()暴涨,且多数millis在 120–300ms 之间 - 根本原因不是“用了事务”,而是事务封装了原本就慢的操作;profiler 只认单条语句耗时,不认事务上下文
- 注意:事务中的
commitTransaction或abortTransaction命令本身几乎不耗时,极少被记录
如何临时降低system.profile写入频率(仅限排查期)
不能关 profiling(否则看不到瓶颈),但可以缩小它的“敏感度”——用 sampleRate 控制采样比例,或提高 slowms 阈值快速过滤掉毛刺。
-
db.setProfilingLevel(1, { slowms: 300, sampleRate: 0.3 }):只记录 >300ms 的操作,且其中仅 30% 被写入system.profile -
sampleRate是浮点数,0.1表示 10%,1表示 100%(默认);低于 1 会丢失部分样本,但能缓解 capped collection 覆盖过快的问题 - 该设置只对当前数据库生效;若事务跨库(比如读
users、写logs),需分别在两个库执行setProfilingLevel - 别用
slowms: 0—— 它等价于level: 2,会把所有操作都记下来,IO 压力陡增
怎么定位事务里哪一步真慢(而不是调阈值糊弄)
靠 system.profile 字段组合过滤,重点看 ns(命名空间)、planSummary 和 docsExamined,而不是只盯 millis。
- 查事务内最耗时的查询:
db.system.profile.find({ ns: /myapp\./, op: "query", millis: { $gt: 200 } }).sort({ millis: -1 }).limit(5) - 找全表扫描:
db.system.profile.find({ planSummary: "COLLSCAN", ns: "myapp.orders" }) - 看锁等待是否拖累:
db.system.profile.find({ "lockStats.timeAcquiringMicros": { $gt: 10000 } })(>10ms 锁等待值得警惕) - 注意:
millis是总耗时,可能包含网络延迟、锁等待、磁盘 IO;真正要优化的是docsExamined / nReturned比值大的操作
永久配置必须写进mongod.conf,否则重启就丢
shell 里执行的 db.setProfilingLevel 是运行时配置,副本集主节点重启后自动失效。生产环境必须落盘。
- 在
/etc/mongod.conf里加这段(YAML 格式):operationProfiling: mode: slowOp slowOpThresholdMs: 200 sampleRate: 0.5
- 改完必须重启
mongod(systemctl restart mongod),不能只 reload - 验证是否生效:
db.getProfilingStatus()必须返回你刚配的slowms和sampleRate,且"was"不是0 - 副本集里,这个配置要同步到所有节点的配置文件,但 profiling 日志只写主节点的
system.profile
事务慢的本质从来不在“事务”二字,而在里面那条没加索引的 find、那个没设 maxTimeMS 的聚合、或者那个在循环里反复执行的 updateOne。调 slowms 只是让日志少点,查 system.profile 里的 planSummary 和 docsExamined 才是动刀子的地方。


















