我不是 Mongo 内存管理方面的专家,但有些事情让我感到困惑。我使用 Mongo 2.4.9,并且我有三个节点的副本集。我执行了 db.serverStatus().mem 并发现映射的大小非常高,为 47GB:
db.serverStatus().mem
{
"bits" : 64,
"resident" : 266,
"virtual" : 101491,
"supported" : true,
"mapped" : 47402,
"mappedWithJournal" : 65730
}
db.stats(1024) 的结果
{
"db" : "xxxxx",
"collections" : 7,
"objects" : 670488,
"avgObjSize" : 2890.6140721385023,
"dataSize" : 1892697,
"storageSize" : 2273304,
"numExtents" : 49,
"indexes" : 42,
"indexSize" : 399378,
"fileSize" : 10416128,
"nsSizeMB" : 16,
"dataFileVersion" : {
"major" : 4,
"minor" : 5
},
"ok" : 1
}
以兆字节为单位
"dataSize" : 1848mb
"storageSize" : 2220mb
"fileSize" : 10172mb
工作集信息:
"workingSet" : {
"note" : "thisIsAnEstimate",
"pagesInMemory" : 152599,
"computationTimeMicros" : 31143,
"overSeconds" : 1728
}
大小 (Mb) = 152599*4kb -> 转换为 Mb = 596 Mb
我的问题是,为什么映射内存的大小比文件大小大 4.2 倍,比存储大小或数据大小大 15159 倍?映射内存继续缓慢增长。大约两周前,它大约是 32gb。
笔记:
OS: Red Hat Enterprise Linux Server release 5.7 (Tikanga)
Physical memory: 3892Mb
我读过这个文章但仍然不明白为什么考虑到实际数据(文件大小)足够小,映射内存的大小会这么大。
谢谢。
答案1
从输出中列出的映射数字db.serverStatus()
基本上是使用以下方法映射到内存中的所有数据文件的测量值映射。您列出的后续命令要么针对单个数据库(db.stats()
),除非您在所有数据库上运行它并将数字加在一起,否则它不会对所有数据库都等效。或者,它们测量完全不同的东西(工作集),这将非常依赖于您最近对数据库所做的操作,并且不会超出您的物理内存。
关于数据库,没有副本集只有一个数据库,总是有本地数据库,它包含用于复制的 oplog,并且(至少)将包含在映射图中,用于预分配的任何空白空间也将包含在内。
您应该发现映射的数字与数据库中数据文件的实际大小非常吻合dbpath
。如果数据库正在运行,那么日志也会存在,包括日志文件夹将为您带来mappedWithJournal的数字(如果数据库完全关闭,日志文件将在启动时被删除并重新分配)。