MongoDB使用提早写日志到磁盘journal来保证写操做的持续性,并提供崩溃恢复。在将数据变更写入数据文件以前,MongoDB将更改写入journal。若是MongoDB进程须要终止或者在将更改从journal写入数据文件以前遇到错误,MongoDB可以从新执行写操做来维持数据库的一致性。html
若是没有journal,若是mongod意外退出,你要预设你的数据处于不一致状态,须要进行repair,或者最好从副本集中选择一个数据一致的成员,从新进行数据同步。web
启用了journal以后,若是mongod意外退出,程序能够从journal中恢复出任何数据,数据仍旧处于一致性状态。默认状况下,没有记录到journal的写入内容的丢失不超过100毫秒。mongodb
启用了journal,若是你须要整个数据集都驻留在内存里,你须要足够的RAM来容纳整个数据集以及“写工做集(write working set)”,“写工做集”是你但愿看到的私有视图重映射间的惟一数据(The “write working set." is the amount of data you expect to see written between re-mappings of the private view),更多信息,请参考Storage Views used in Journalingshell
重要数据库
在 2.0 版更改: For 64-bit builds of mongod, journaling is enabled by default. For other platforms, see journal.缓存
默认64位操做系统,启用了journalling安全
显示启用journalling,启动mongod时添加参数--journalapp
若是journal文件存在,mongod启动后,进程须要预配置新的日志文件。在这个操做过程当中,只有完成了预配置,mongod才开始监听链接:对有些操做系统,这可能持续几分钟。在这个过程当中,应用和mongo shell不可用。less
警告性能
生产系统不要禁用journaling。若是你的mongod实例由于某种缘由意外未干净退出,且你没有运行journaling,这种状况下你须要从未受影响的副本集成员中或者备份中恢复数据。
要禁用journaling,启动mongod添加参数--nojournal
你能够经过食用getLastError命令和j参数来获取提交确认,详细信息,参考Internal Operation of write concern
为了不预分配带来的延迟,你能够拷贝其它mongod实例的journal目录到当前目录来实现文件预配置。
预配置文件不包含数据。后续删除是安全的。不过若是你启用了journaling重启了mongod,这些文件会从新被建立。
例如
如下顺序为监听在27017端口的mongod进程预配置了journal文件。
For demonstration purposes, the sequence starts by creating a set of journal files in the usual way.
为journal文件建立一个临时目录:
mkdir ~/tmpDbpath
启动mongod进程,该进程使用此临时目录存放journal文件:
mongod --port 10000 --dbpath ~/tmpDbpath --journal
当看到以下输出时,代表mongod已经建立好这些文件,使用CONTROL+C中止mongod实例:
web admin interface listening on port 11000
讲临时目录中的journal文件移动到新实例使用的文件目录中:
mv ~/tmpDbpath/journal /data/db/
启动新实例:
mongod --port 27017 --dbpath /data/db --journal
使用以下命令监控journal状态:
ServerStatus显示实例状态信息,访问性能。
journalLatencyTest
使用journalLatencyTest测量在append-only模式下,须要多久才能写入磁盘。你能够在空闲系统上运行该命令得到journaling的基线同步时间。你也能够在繁忙的操做系统上运行该命令获取同步时间。若是journal目录和数据目录在同一个卷上,该时间可能会稍高。
journalLatencyTest还能够检测磁盘是否开启了写缓存。若是磁盘不是SSD,而写入时间很是低(好比不足2毫秒),磁盘驱动器极可能缓存了写操做。这种状况下,系统要启用直接写入(write-through),除非你的磁盘控制卡有电池。(unless you have a disk controller card with battery backed RAM)
使用journalCommitInterval更改组提交间隔。容许范围为2-300ms
值越低日志的持续性越好,但代价是下降磁盘性能。
若是遇到数据库崩溃,MongoDB须要进行日志重演,完成以后服务才变的可用。若是MongoDB必须重演日志,在日志输出端会进行提示。
该状况不需进行repairDatabase
mongd开启了journaling运行过程当中, MongoDB stores and applies write operations in memory and in the journal before the changes are in the data files.
MongoDB开启日志后,在定义好的dbpath内建立一个日志目录。日志目录下存放日志文件,这些文件是预先写入的redo日志。这个目录同时还存放一个最后序列数字文件。若是数据库被干净地关闭,journal目录下的文件会所有被删除。
日志文件是追加式文件,这些文件有一个前缀j._。当日志文件达到1G,MongoDB建立一个新的日志文件。当日志文件中全部的写操做已经被应用,该文件会被删除。除非每秒钟你写入了不少数据,不然该目录下应该只包括两到三个日志文件。
若是想一想限制日志文件最大为128M,使用在mongod运行时使用smallfiles命令。
重要
If you place the journal on a different filesystem from your data files you cannot use a filesystem snapshot to capture consistent backups of a dbpath directory.
journaling在mongodb中添加了三个存储视图
共享视图(shared view)存储了要上传到MongoDB数据文件中的修改过的数据。共享视图是惟一可以直接访问MongoDB数据文件的视图。当实例开启了journaling,mongod会要求系统将磁盘上已存在的数据文件映射到共享视图的内存视图(sharedview memory view)。操做系统映射这些文件,但不加载它们。若是后续须要,mongoDB会将这些数据文件加载进来。
私有视图(private view)存储了须要读操做的数据。MongoDB maps private view to the shared view and is the first place MongoDB applies new write operations.
日志是一种记录在磁盘上的视图,该视图存储了新的写入操做,这些操做已经被记录在私有cache中,但尚未写入到数据文件。日志提供了数据持续性。若是mongod实例崩溃,但没有将数据写入数据文件,日志能够经过将数据重演到共享视图,最后写入数据文件。
MongoDB将写操做复制一组提交(journal in batches called group commits)。默认,每100ms之行一次组提交:即每100msmongodb将该100ms内的全部命令一次提交。这种组提交策略下降了对性能的影响。
日志存储原始操做,以便MongoDB能够将其进行重组:
写操做发生时,MongDB将数据写入RAM中的私有视图,而后将其批量复制到日志。日志将这些操做记录到磁盘。mongodb以条目形式在journal的前向指针中添加操做。每一个条目描述了在数据文件的哪些字节处有写操做。
As part of journaling, MongoDB routinely asks the operating system to remap the shared view to the private view, for consistency.
MongoDB以后将journal的写操做应用到共享视图。此时,共享视图和数据文件变的不一致。
默认每隔60s,MongoDB请求操做系统将共享视图内容刷入数据文件。这保证了老是最新的。
当MongoDB将写操做刷入数据文件时,MongoDB将写操做从journal's behind pointer中移除此操做。
When MongoDB flushes write operations to the data files, MongoDB removes the write operations from the journal’s behind pointer. The behind pointer is always far back from advanced pointer.
做为日志记录的一部分,为了一致性,MongoDB会按期要求操做系统从新将共享视图映射进私有视图。
http://mongodb-documentation.readthedocs.io/en/latest/administration/journaling.html