Page fault 在大多数数据库中都会存在,页面错误的定义是当mongodb读取数据时,发现数据不再常驻的cache中,而需要从等待从磁盘读取数据到内存中的页面,这些页面就被称之为 page fault.
PAGE FAULT 主要产生问题的是在用户在读取,或进行DML 操作时所需要读取的数据不再虚拟内存中,而需要等待从磁盘中获取这些数据。
鉴于以上的原理,page fault 的问题产生基于空余的内存不足的问题,在系统中使用页面的情况会经常判断是否有空余的页面空间,基于剩余的空余页面的不足,会频繁驱逐目前已经不在使用的页面中的数据,并且加载目前需要使用的页面,基于内存不足的情况,这样的获取信息和驱逐页面的工作会频繁的进行。
我们可以基于db.serverStatus()来进行相关的信息的分析工作,
var info = db.serverStatus()
info.wiredTiger.cache['pages read into cache']
info.wiredTiger.cache['unmodified pages evicted']
通过动态比较上面的两个系统的监控值,为当前的内存不足所引起的问题。如果读取的 page read into cache 与 unmodified pages evicted 页面之间存在正比的关系,就很有可能是因为内存不足,或查询中经常有一些大型的获取数据的查询并且可能没有走索引导致。
同时我们还可以通过查看当前系统的内存是否充足,如FREE 剩余内存多少,是否已经使用SWAP 方式。同时打开慢查询分析,查看是否当前有一些走了全表扫描的语句正在批量执行。
这里画一个问题分析的逻辑结构图如何解决在发现page faults 后的操作。
db.serverStatus().extra_info.page_faults , 也可以通过extra_info命令来获取系统内告知的 page_faults的数量。
除此以外,我们还可以通过一些其他的手段来判断你当前的内存是否够目前的运行使用
1 可以将当前的经常使用的collection 进行统计
2 通过db.collection.totalIndexSize() 来收集当前热度很高的索引的大小有多少,如果这些索引已经超过了当前的 wiredtiger cache size 就需要注意当前的内存扩容的问题了。
另外根据官方文档中的文字介绍
Ensure Indexes Fit in RAM — MongoDB Manual
Indexes do not have to fit entirely into RAM in all cases. If the value of the indexed field increments with every insert, and most queries select recently added documents; then MongoDB only needs to keep the parts of the index that hold the most recent or "right-most" values in RAM. This allows for efficient index use for read and write operations and minimize the amount of RAM required to support the index.
实际上在MONGODB 中并不是一定要把整体的索引都装载到内存中的数据库,MONGODB 仅仅需要保证最近经常访问的最右侧的值在内存中即可,对于较大的索引与不充分的内存的情况是有一定的帮助和改善的。