mongodb 服务端事务统计需通过 serverstatus.transactions 获取,包括 totalcommitted 和 totalaborted 累计值,仅 primary 节点返回有效数据,secondary 始终为空;应用层日志易漏报回滚,不可靠;推荐用 mongodb_exporter 抓取指标并配置 prometheus 告警。

如何查看 MongoDB 服务端的事务提交/回滚统计
MongoDB 本身不提供直接的 transaction_commit_count 或 transaction_rollback_count 指标,但可通过 serverStatus 中的 transactions 字段间接获取。该字段从 MongoDB 4.2 起可用,需连接到 primary 节点 并拥有 clusterMonitor 权限。
执行以下命令即可读取当前累计值:
db.runCommand({ serverStatus: 1 }).transactions
返回结果中关键字段包括:
-
totalStarted:已启动事务总数(含未完成) -
totalCommitted:成功提交数 -
totalAborted:显式中止或隐式回滚总数(含超时、错误、abortTransaction) -
currentActive:当前活跃事务数(非累计)
注意:totalAborted 不区分“主动调用 abortTransaction”和“因异常自动回滚”,它只反映最终未提交的事务数量。
为什么不能靠应用层日志准确统计回滚次数
应用代码里写 session.abortTransaction() 或抛出异常触发回滚,看起来可控,但实际漏报严重:
- 网络中断、会话超时(
maxTimeMS触发)、primary 切换等场景下,驱动可能静默丢弃事务,不走你的catch分支 - 使用高级 API(如 Mongoid
transaction块)时,回滚由框架内部处理,after_rollback回调不一定覆盖所有失败路径 - Go 的
WithTransaction在遇到TransientTransactionError会自动重试,你看到的日志可能是第 2 次提交成功,而前 1 次回滚完全没暴露
所以依赖 console.log("rollback!") 或埋点计数,数值一定偏低,仅适合调试,不可用于监控告警。
在 Prometheus + Grafana 中抓取并可视化这些指标
如果你用 mongodb_exporter(推荐 v0.30.0+),它会把 serverStatus.transactions 映射为如下指标:
mongodb_transactions_total{state="committed"}mongodb_transactions_total{state="aborted"}mongodb_transactions_active
配置采集时注意两点:
- 确保 exporter 连接的是 replica set 的 primary,secondary 不返回
transactions字段 - 检查 exporter 日志是否报
not authorized on admin to execute command { serverStatus },需授予clusterMonitor角色
典型告警规则示例(PromQL):
rate(mongodb_transactions_total{state="aborted"}[5m]) > 10
表示每分钟回滚超过 10 次,大概率存在业务逻辑冲突或锁争用,需立刻排查。
容易被忽略的细节:副本集状态影响指标可见性
serverStatus.transactions 在 secondary 节点上始终为空对象 {},即使它参与了事务的 majority writeConcern 确认。这意味着:
- 不能在任意节点上查这个指标——必须路由到 primary
- 如果 primary 刚完成故障转移,
totalCommitted和totalAborted会重置为 0(这是正常行为,不是数据丢失) - 监控系统若轮询多个节点且未做 primary 识别,图表会出现断崖式归零,误判为服务重启
真正稳定的长期趋势分析,必须绑定到固定 primary 的 endpoint,或通过 replica set 的 isMaster 命令动态发现主节点后再采集。











