一、无Journaling的mongo运行原理

  在没有使用journal功能时,mongo数据库只将数据的内存映射加载到共享视图shared,不需要将数据加载到视图。当需要读取数据时,通过shared中的内存映射找到数据在次盘整的位置,将数据加载到shared中,同时返回到客户端,也就是按需加载。当客户端对数据进行修改或者写操作时,将数据添加到shared中,每60秒shared钟的数据返写到磁盘。如下图所示:

二、存在Journaling的mongo运行原理

  在添加journal功能之后,就会产生一个private视图。整个的运行操作主要有一下几部分组成。

  

  在对数据进行操作,需要以下几步进行执行:

  1、获取数据

    在打开journal功能后,数据会从磁盘获取内存映射,加载到shared中,同时shared中的内存映射会同步到private中一份,在客户端获取数据时,通过内存映射从磁盘加载到shared和private中,客户端从private获取数据。图示如下:

      

  2、写数据、批量写入journal和刷新shared

    客户端修改或者写操作时,数据会存储到private中,private中的数据会周期性的写入到journal文件中,这个周期默认是100ms,是通过journalCommitInterval来控制的。同时,journal文件中的数据操作会写入shared中,批量写入到journal可以提高对数据库的并发操作。如果数据库出现故障,在这段时间内的数据可能丢失。图示如下:

    

  3、数据库若崩溃

     一旦数据库崩溃,在重新启动数据库时,journal文件中的数据库操作会再次刷新到shared中。图示如下:

      

  4、重新映射、刷新磁盘

   journal中存储的是数据操作指令,只是对shared中的数据进行操作。在将journal中的内容刷新到shared中后,shared中的数据会重新映射private中,由于shared中的数据与private中的数据不一致,在重新映射后,private的大小一般为0。同时,shared中的数据也会周期性的将数据刷新到磁盘,这个周期默认为60s。在刷新磁盘成功后,journal文件中的数据会自动删除。图示如下: