直接用db.currentop()实时抓长事务,需连admin库并过滤secs_running>5、lsid存在、waitingforlock等字段;system.profile靠lsid和txnnumber聚合识别事务操作;mongostat/mongotop无法获取事务上下文,副本集须各节点单独查。

直接看 db.currentOp(),别等它自动告警——生产环境里事务卡住几秒就可能拖垮整个服务链路。
怎么用 db.currentOp() 快速揪出长事务
它不是“查历史”,而是实时快照,适合立刻响应。关键不是全量查,而是加条件过滤:
- 必须连到
admin数据库执行,否则看不到其他用户的操作:db.getSiblingDB("admin").currentOp({ "secs_running": { "$gt": 5 } }) - 只关心事务?加
"lsid": { "$exists": true },排除普通查询干扰 - 想区分是真执行慢,还是被锁住?重点看
waitingForLock字段:true表示在排队,false才说明命令本身耗时高 - 别只盯
secs_running,它精度只有秒级;更准的是microsecs_running,尤其对亚秒级事务敏感
system.profile 里怎么识别事务操作
Profiler 不记 commitTransaction,但会记事务里的每一条实际命令——靠 lsid 和 txnNumber 关联才是唯一可靠方式:
- 先确保已开启:
db.setProfilingLevel(1, { slowms: 50 })(阈值按业务容忍下调,别死守默认 100ms) - 查日志时必须聚合:
db.system.profile.aggregate([ { $match: { lsid: { "$exists": true } } }, { $group: { _id: { lsid: "$lsid", txnNumber: "$txnNumber" }, ops: { $push: "$$ROOT" }, total_ms: { $sum: "$millis" } } }, { $sort: { total_ms: -1 } } ]) - 看到
"planSummary": "COLLSCAN"或keysExamined远大于nReturned?基本就是事务内某条find或update没走索引 - 注意:
command字段里不会出现 “transaction” 字样,只会出现"find"、"update"等真实动作
为什么 mongostat 和 mongotop 对事务监控作用有限
它们统计的是宏观吞吐和集合 I/O,但事务的瓶颈往往藏在语义层:
-
mongostat的locked %高,只能告诉你“有锁竞争”,但不知道是哪个事务在持锁、锁了什么资源 -
mongotop显示某个集合写入耗时高,可如果这个集合被多个事务交叉更新,你无法判断是单个事务太重,还是十几个小事务在排队抢锁 - 两者都看不到
lsid、txnNumber、waitingForLock这类事务上下文字段,纯靠猜容易误判 - 真正要定位“为什么这个事务跑了 8 秒”,还得回到
currentOp+explain("executionStats")组合,复现那条具体命令
事务监控最易被忽略的一点:副本集场景下,db.currentOp() 默认只返回当前节点视图。如果事务跨分片或涉及主从同步延迟,必须分别登录 primary 和 secondary 节点单独查——没有全局视图,靠一个命令覆盖全部节点是不现实的。











