事务导致 WiredTiger 脏页飙升,因未提交前修改驻留内存并标记为 dirty;长、大、高频事务及非索引读操作均延长脏页生命周期,提交后不立即刷盘,受 journal、cache_size 和 read/writeConcern 配置影响。

事务本身不直接占用 WiredTiger 缓存,但长事务、大事务或高频小事务会显著推高缓存中脏页(dirty pages)比例,触发强制淘汰甚至阻塞写入线程。
为什么事务会让 wiredTiger.cache.bytes_dirty 快速飙升
WiredTiger 的事务在提交前,所有修改都保留在内存中的 page 中,并标记为“脏”。这些 page 会持续驻留 cache,直到被 eviction 线程刷盘或事务显式提交。问题不在事务开关本身,而在以下行为:
- 单个事务内批量写入超 10MB 数据(比如
bulkWrite插入上万文档),导致大量 page 被锁定为 dirty 状态 - 事务执行时间 > 5 秒(尤其含慢查询、网络等待、应用层逻辑卡顿),延长 dirty page 生命周期
- 高并发下每秒开启数百个短事务(如每个 HTTP 请求启一个事务),造成 eviction 线程来不及清理,
bytes_dirty持续 >20% - 事务中混用读操作(尤其是
find()扫描未命中索引的集合),导致大量 page 被加载进 cache 但未释放
db.runCommand({ "commitTransaction": 1 }) 提交后缓存没降?检查这三点
提交事务只是将变更标记为可持久化,并不立即刷盘。WiredTiger 仍按后台策略管理 page 回收。常见误判点:
- 未启用
journal: true(默认开启),导致提交后日志未落盘,eviction 线程不敢回收对应 page - 配置了过低的
cache_size(如仅 2GB),即使事务已提交,cache 已满,旧 page 无法被新数据替换,脏页被迫滞留 - 使用了
readConcern: "snapshot"或长周期游标,WiredTiger 需保留历史版本页以支持快照隔离,间接抬高 dirty 占比
验证方式:提交后立刻运行 db.serverStatus().wiredTiger.cache,观察 pages evicted by application threads 是否在增长;若为 0,说明 eviction 受阻,需查 eviction-target 和 eviction_dirty_target 配置。
调整事务粒度时,writeConcern 和 readConcern 的隐性开销
这两项看似只影响一致性语义,实则深度绑定 WiredTiger 缓存行为:
-
writeConcern: { w: "majority" }会强制等待多数节点 journal 落盘,延长事务生命周期,增加 dirty page 滞留窗口 -
readConcern: "linearizable"要求主节点最新 oplog 时间戳,可能触发更激进的 cache 预热和 page 锁定 - 混合使用
readConcern: "snapshot"+ 大范围aggregate(),会使 WiredTiger 为每个 stage 保存独立版本页,内存放大效应明显
建议生产环境事务默认用 readConcern: "local" 和 writeConcern: { w: 1 },仅在强一致场景按需升格,并配合同步监控 wiredTiger.cache.pages_requested_from_cache 突增情况。
真正有效的事务缓存减压手段:不是关事务,而是控节奏
与其禁用事务,不如用轻量机制替代重事务。关键在把“数据库级原子性”下沉到应用逻辑或分片边界:
- 对非金融类业务,用两阶段应用层补偿(如先写状态表再发 MQ)替代跨集合事务
- 拆分大事务:将单次插入 5000 条改为每 500 条一个事务,配合
maxTimeMS: 3000防死锁 - 读多写少场景,用
findAndModify替代startTransaction+updateOne+commitTransaction,减少 session 开销 - 确认业务允许最终一致性时,关闭
journal(仅限测试/日志类集合),cache_size可降低 30%,但必须接受 crash 后最多 100ms 数据丢失
最易被忽略的一点:WiredTiger 的 cache 压力不是孤立指标。当 bytes_dirty >20% 且 pages written from cache 持续 eviction=(threads_max=6) —— 但后者会吃 CPU,得看监控里 system.cpu.user 是否同步飙高。


















