删除文档不会降低 resident 内存值,因 wiredtiger 仅逻辑删除且不主动归还 cache 空间;resident 反映 mongod 进程实际物理内存占用,受 cachesizegb 配置、进程重启或极端负载下自动收缩影响,与 storagesize 无直接关系。

删除文档不会降低 resident 内存值,这是 WiredTiger 存储引擎的正常行为,不是内存泄漏。
为什么 db.serverStatus().mem.resident 不下降
WiredTiger 的内存管理分两层:一是操作系统级物理内存(resident),二是引擎内部的 cache(wiredTiger.cache.bytes currently in the cache)。执行 remove 或 deleteMany 只是逻辑删除,不触发 cache 淘汰或内存归还。WiredTiger 会持续保留已分配的 cache 空间,直到被新数据填充、后台淘汰线程回收,或显式调低 cacheSizeGB 配置并重启进程。
-
resident值反映的是 mongod 进程当前实际占用的物理内存,它由 tcmalloc 分配器管理,不会因文档删除而主动释放回系统 - 真正受删除影响的是 cache 内部的“脏页比例”和“空闲 page 数”,但这些变化不等于
resident下降 - 即使集合为空,只要 cacheSize 配置未变,WiredTiger 仍会维持接近上限的 cache 占用
compact 能不能降低 resident
不能。 db.runCommand({compact: "coll"}) 只作用于磁盘文件碎片整理和空间复用,它不触碰内存 cache 大小,也不触发内存释放。它可能间接减少后续写入对 cache 的压力,但不会让 resident 瞬间回落。
- 该命令在 WiredTiger 层做 extent 合并与 truncate,只影响
.wt文件大小和storageSize - 执行期间会加库级写锁,阻塞所有写操作,但对内存占用无直接干预
- 若你观察到 compact 后
resident略有下降,那通常是 cache 淘汰线程恰好在此期间清掉了部分 clean page,属巧合,不可依赖
真正能降低 resident 的方法有哪些
只有三类操作会影响 mongod 进程的物理内存驻留量:配置调整、进程重启、或极端负载下的自动收缩(极少见)。
- 修改
wiredTigerCacheSizeGB并重启 mongod —— 这是最可控的方式;新值生效后,cache 初始化即按新上限分配,resident会逐步回落 - 手动触发 cache 淘汰(不推荐):通过
db.runCommand({setParameter: 1, wiredTigerEngineConfigString: "cache_size=1G"})动态改参(仅 MongoDB 4.2+ 支持),但效果不稳定,且可能引发写阻塞 - 等待长时间低负载:WiredTiger 的 eviction thread 在 cache 使用率低于阈值(如
cache_size * 0.8)且无写压力时,会缓慢释放 clean page,但这个过程以小时计,无法用于应急
别把 storageSize 和 resident 混为一谈
这是最容易误判的点。一个集合 storageSize 很小,不代表 resident 就低;反过来,resident 高也不代表磁盘快满了。
-
db.collection.stats().storageSize是该集合在磁盘上占用的物理字节数(含碎片),受compact或drop影响 -
db.serverStatus().mem.resident是整个 mongod 进程吃掉的物理内存,主要由 WiredTiger cache + 连接/请求上下文 + tcmalloc 元数据构成 - 两者无直接换算关系;例如空集合 + 32GB cache 配置,
resident仍可稳定在 30GB 左右
关键要分清:你真正想解决的是磁盘空间紧张,还是内存 OOM 风险?前者盯 storageSize 和 df -h,后者才看 resident 和系统 free -m。WiredTiger 的 cache 设计本就偏向“宁可多占、不轻易放”,强行干预反而破坏其性能模型。











