`
shingo7
  • 浏览: 18827 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

MongoDB Journaling 机制

阅读更多

当MongoDB运行在journal开启的状态下, 写操作会在写入磁盘数据文件之前先写入内存和journal文件。本文讨论MongoDB 系统中journaling 的实现和技术细节。更多关于配置、调试、管理journaling的信息见管理Journaling

 

(译者注:官方文档并未将journalling机制说清楚,我在白板上画了一幅图来辅助读者理解,在后边的篇幅中会有对这幅图的描述)

 

 

Journal 文件

 

Journaling开启后, MongoDB会在定义好的dbPath路径下创建一个 journal子目录,dbpath路径默认为/data/db。这个目录用来存放journal文件,文件中记录的是write-ahead日志。

 

(译者注:即WAL,预写式日志。数据库系统在运行时将对数据库的修改写到redo日志中而不是数据文件,然后redo日志通过checkpoint做group commit刷到最终的数据文件里。这是大多数数据库系统采用的做法)

 

目录下还有一个文件来保存某个最近的序列号。

 

(译者注:这个文件是journal目录下的lsn文件,里边保存的序列号并非是journal文件的序列号。这个就说来话长了,上边的注释提到写操作在写入数据文件之前会写到journal文件中,而在写入journal文件之前会先写入到一块内存区域,这个内存区域叫private view,官方表示说private view的数据默认每100ms刷到journal文件中,但其实是从private view分批刷到某个临时内存区域,然后从临时内存区域再刷到journal文件,这个刷到临时内存的批次就是lsn文件中保存的序列号)。

 

一次正常的退出会删除journal目录下所有文件,而一次非正常退出(比如崩溃)则不会;重启mongod进程时会根据journal下的文件来恢复数据以达到数据一致。

 

Journal文件是append-only文件,文件名以j._为前辍。当超过1G时,MongoDB会创建一个新的文件。一旦某个journal文件的数据全部刷到数据文件之后,MongoDB会删掉这个journal文件,因为它起不到恢复系统的作用了。除非你的系统每秒写入大量数据,否则通常情况下journal目录应该只有两三个文件。

 

如果你愿意的话,可以在启动mongod进程时设置storage.smallFiles属性,它会将journal文件大小限制到128M

 

如果要提高journal文件非常频繁的顺序写入性能,你可以将journal目录放置在和数据文件不同的文件系统下。

 

 

重要:

如果将journal和数据文件放置在不同的文件系统中,将不能使用单独使用文件系统快照来备份dbPath目录下的文件。在这种场景下,先使用fsyncLock()来确保数据文件一致性,等快照生成完毕之后使用fsyncUnlock()来释放锁定。

 

注意:

根据你的文件系统的不同,开启journaling第一次启动mongod进程时系统可能会有点滞后,因为要为journal文件预分配空间。

如果mongod进程认为预分配journal文件比在需要时再去创建文件更高效,MongoDB会事先将它分配好。预分配文件的时间可能会持续几分钟,在这段时间内是连接不了数据库的。这是一次性的行为,在以后的调用中不会发生。

 

如果要避免预分配带来的滞后,参见官方文档 Avoid Preallocation Lag

 

Journaling中的存储视图

 

整个Journaling机制中有了3个内部存储视图来服务于MongoDB。

 

shared view存储修改后的数据然后刷到磁盘的数据文件中。shared view是唯一一个能够直接访问数据文件的视图。当运行时journaling开启,mongod进程会让操作系统将磁盘上所有的数据文件映射到shared view虚拟内存。操作系统只映射文件不会加载真实数据。只有在需要时才会将数据加载到shared view中。

 

private view中的数据用来响应读操作。private view是一个接收MongoDB写操作的地方。当journal提交后,MongoDB将private view的更改复制到shared view, 这些更改最终通过shared view刷到磁盘数据文件中。

 

Journal文件是一个基于磁盘的视图,在数据改动刷到磁盘数据文件之前它用来存储private view接收到的写操作。Journal为数据库提供了健壮性,如果 mongod进程在将数据写入到磁盘数据文件之前崩溃了,下次启动时会回放 journal中的写操作到shared view,并最终会将改动刷到磁盘数据文件中。

 

译者注:官方文档对视图的描述比较简单,这里我对整个持久化流图做了一下梳理,也是对文章开头我画的图的解释。

① Mongodb启动时将数据文件映射到shared view,这是内存映射,并非加载所有数据。

② Shared view映射到private view。

③ Private view通过group commit将客户端的写操作写入到journal文件,其实这中间还经历了一次aligned buffer,官方所说的group commit其实是从aligned buffer到journal文件。

Jaournal文件将写操作回放给shared view。

Shared view将数据改动刷到磁盘数据文件。

Shared view重新映射到private view。

 

Journaling如何记录写操作

 

MongoDB将写操作按批次复制到journal文件, 这种方式称之为批量提交。将数据按照“批量提交” 可以有效的减少journaling机制的性能开销,因为每次提交发生时都会阻塞住所有写操作。批量提交的默认时间间隔见commitIntervalMs参数。

 

Journaling存储的都是原生操作,MongoDB能够利用它们来重放以下操作:

  • 文档的插入/更新

  • 索引的修改

  • 对命名空间元数据进行修改

  • 创建和删除数据库,以及一些相关数据文件

 

当一个写操发生时,MongoDB将数据写入内存中的private view,然后从private view将写操作分批复制到到journal文件。Journal文件存储在磁盘上以保证健壮性。每条journal数据都描述了写操作让数据文件发生变化的具体地址。

 

接下来MongoDB将journal中的写操作提交到shared view中,这时shared view和数据文件中的数据会不一致。

 

默认情况下每隔60秒,MongoDB通过操作系统将shared view的数据改动刷到磁盘上,这样使得最新的写操作能体现在数据文件中。有时操作系统刷磁盘的间隔会超过60秒,特别是在系统空闲内存比较少的时候。

 

当MongoDB将数据往磁盘上刷时,会记住这些刷过的数据。一旦某个journal文件上记录的所有操作都被刷到数据文件中后,这个文件就再也起不到恢复数据的作用了,MongoDB会删除这个文件,也可能回收它用作一个新的journal文件。

 

做为整个journaling机制的一部分, MongoDB会照常请求操作系统将shared view重新映射到private view,这样是为了节约物理内存。基于一次新的重映射,操作系统会将物理内存页共享给shared view和private view。

 

(译者注:shared view初始映射到private view时,private view是只读的,当写操作进来时,mongodb将private view中映射数据的所在页变更为可写,然后从数据文件复制一份真实数据的拷贝,并将写操作的数据写入进来。只有在这时private view才会单独的去消耗内存,初始映射的时候是没有内存消耗的,所以官方说初始时是共享物理内存页)

 

注意:

shared view和磁盘数据文件之间的这部分交互和不使用journaling时大致是一样的, 同样都是MongoDB每隔60秒请求操作系统将内存中的数据改动刷到数据文件中。

 

分享到:
评论

相关推荐

    MongoDB Sharding 机制分析

    MongoDB Sharding 机制分析及实现

    30分钟学MongoDB系列 ——MongoDB的安全机制和高级管理篇

    1.分篇章进行学习,内容控制30分钟内 2.1个月疗程,不要放弃治疗哦 3.图文并茂,有问题请发到邮箱

    课时8:MongoDB数据库安全机制.mp4

    MongoDB数据库

    mongodb数据库认证机制更改

    mongodb集群的认证机制的修改,经过一步一步尝试总结的方法,希望大家看看!

    Linux安装mongodb客户端

    sudo vim /etc/yum.repos.d/mongodb-org-4.2.repo 写入: [mongodb-org-4.2] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/x86_64/ gpgcheck=1 enabled=1 gpg...

    MongoDB应用设计模式

    资源名称:MongoDB应用设计模式内容简介:无论是在构建社交媒体网站,还是在开发一个仅在内部使用的企业应用程序,《MongoDB应用设计模式》展示了MongoDB需要解决的商业问题之间的连接。你将学到如何把MongoDB设计...

    MongoDB笔记.docx

    一、MongoDB简介 3 二、MongoDB结构 3 二、MongoDB 数据库关系型(这里并不是值关系型数据库的关系) 3 1、MongoDB一对一关系型 3 2、MongoDB一对多关系型 4 3、MongoDB多对多关系型 4 三、创建数据库(mongodb_test...

    如何安装MongoDB 如何使用MongoDB

    本课程是一套关于MongoDB应用开发的实战性教程,名为《深入浅出MongoDB应用实战开发(基础、开发指南、系统管理、集群及系统架构)》,教程侧重于讲解MongoDB的常用特性及高级特性,从实际开发的角度出发对MongoDB...

    mongotriggers:允许mongodb触发机制类似于RDBM触发机制

    mongodb-triggers是一个轻量级的库,允许实时实时更改通知。 这类似于SQL中的触发器。 可以在Java和JavaScript(MeteorJS)中找到此功能 到底有什么好处呢? 现代应用程序已接近实时响应和更新,这导致要求将数据...

    Jfinal MongoDB插件

    将mongo'DB封装,便于查询 ...支持MongoDB的授权机制(可以使用用户名和密码登录)、支持连接MongoDB副本集、读写分离、安全写入、SSL连接等特性。 内置JFinal和Resty插件。(基于最新版的JFinal和Resty)

    mongodb-linux-x86_64-4.0.18.tgz

    mv mongodb-linux-x86_64-4.0.18 mongodb 3、进入 mongodb 目录创建目录 db 和 logs cd /usr/local/mongodb mkdir db mkdir logs 4、进入到 bin 目录下,编辑 mongodb.conf 文件,内容如下: dbpath=/usr/local/...

    【BAT必备】MongoDB面试题

    【BAT必备】MongoDB面试题【BAT必备】MongoDB面试题【BAT必备】MongoDB面试题【BAT必备】MongoDB面试题【BAT必备】MongoDB面试题【BAT必备】MongoDB面试题【BAT必备】MongoDB面试题【BAT必备】MongoDB面试题【BAT...

    MongoDB图形化管理工具 MongoDB Compass

    MongoDB图形化管理工具 MongoDB Compass

    基于MongoDB的日志系统Mongodb-Log.zip

    mongodb-log 是一个基于MongoDB的Python日志系统。 MongoDB 的 Capped Collection是一个天生的日志系统,MongoDB自己的oplog就是用它来存储的,Capped Collection的特点是可以指定Collection的大小,当记录总大小...

    MongoDB4.2分片及副本集群搭建

    MongoDB4.2分片及副本集群搭建 MongoDB集群 MongoDB分片 MongoDB副本 MongoDB副本集群

    MongoDB(mongodb-org-server_5.0.4_amd64.deb)

    MongoDB Community Server(mongodb-org-server_5.0.4_amd64.deb)适用于适用于Debian10 MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是...

    五、MongoDB 学习PPT

    MongoDB 学习PPT

    MongoDB(mongodb-src-r5.0.4.tar.gz)

    MongoDB Community Server(mongodb-src-r5.0.4.tar.gz)源代码 MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非...

    MongoDB教程基础入门

    教程名称:MongoDB教程基础入门 课程目录:【】MongoDB教程基础入门-代码【】MongoDB教程基础入门01第一讲上【】MongoDB教程基础入门02第一讲下【】MongoDB教程基础入门03第二讲上【】MongoDB教程基础入门04第二讲...

    MongoDB Community(mongodb-linux-aarch64-ubuntu1804-5.0.8.tgz)

    MongoDB Community Server(mongodb-linux-aarch64-ubuntu1804-5.0.8.tgz)适用于Ubuntu 18.04 Arm芯片, MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决...

Global site tag (gtag.js) - Google Analytics