MongoDB实战指南(四):MongoDB的Journaling日志功能
mongoDB的Journaling日志功能与常见的log日志是不一样的,mongoDB也有log日志,它只是简单记录了数据库在服务器上的启动信息、慢查询记录、数据库异常信息、客户端与数据库服务器连接、断开等信息。Journaling日志功能则是mongoDB里面非常重要的一个功能,它保证了数据库服务器在意外断电、自然灾害等情况发生下数据的完整性。尽管mongoDB还提供了其它的复制集等备份措施(后面会分析),但Journaling的功能在生产环境中是不可缺少的,它依靠了较小的CPU和内存消耗,带来的是数据库的持久性和稳定性。
1. 两个重要的存储视图
Journaling功能用到了两个重要的内存视图:private view和shared view。这两个内存视图都是通过MMAP(内存映射)来实现的,其中对private view的映射的内存修改不会影响到磁盘上,shared view中数据的变化会影响到磁盘上的文件,系统会周期性的刷新shared view中的数据到磁盘。
(1) shared view在mongoDB启动的过程中,操作系统会将磁盘上的数据文件映射到内存中的shared view,操作系统只是完成映射,并没有立即加载数据到内存,mongoDB会根据需要加载数据到shared view。
(2)private view 内存视图是为读操作保存数据的位置,是mongoDB保存新的写操作的第一个地方。
(3)磁盘上的Journaling日志文件,是实现写操作持久化保存的地方。mongoDB实例启动时会读这个文件。
2. Journaling工作原理
当mongod进行启动后,首先将数据文件映射到shared视图中,假如数据文件的大小为4000个字节,它会将此大小的数据文件映射到内存中,地址可能为1000000-1004000。如果直接读取地址为100060的内存,我们将得到数据文件中第60个字节处的内容。有一点要注意,这里只是完成了数据文件的内存映射,并不是将全部文件加载到内存中,只有读取到某个地址时才会将相应的文件内容加载的内存中,相当于按需加载。如下图所示:
mongod启动时的内存映射
当写操作或者修改操作发生时,进程首先会修改内存中的数据,此时磁盘上的文件数据就与内存中的数据不一致了。如果mongod启动时没有打开Journaling功能,操作系统将每60秒刷新shared视图对于的内存中变化的数据并将它写到磁盘上。如果打开了Journaling日志功能,mongod将额外产生一个private视图,MongoDB会将private视图与shared视图同步,如下图所示:
shared视图与private视图保持同步
当写操作发生时,MongoDB首先将数据写到内存中的private视图处,注意private视图并没有直接与磁盘上的文件连接,因此此时操作系统不会将变化刷新到磁盘上,如下图所示:
MongoDB写数据到private视图
然后MongoDB将写操作批量复制到journal,journal会将写操作存储到磁盘上的文件上,使其持久化保存,journal日志文件上的每一个条目都描述了写操作更改了数据文件上的哪些字节,如下图所示:
将数据文件的变化写到journal日志文件中
由于数据文件的变化(如在哪个位置数据变成了什么)被持久化到了journal日志文件中,即使此时MongoDB服务器崩溃了,写操作也是安全的。因为当数据库重新启动时,会先读journal日志文件,将写操作引起的变化重新同步到数据文件中去。
当上面的步骤完成后,接下来MongoDB会利用journal日志中的写操作记录引起的数据文件变化来更新shared视图中的数据。如下图所示:
刷新shared视图
当所有的变化操作都更新到shared视图后,MongoDB将重新利用shared视图来映射private视图,方式private视图变得"太脏",使其占用的内存空间恢复到初始值,约为0.此时shared视图内存中的数据与磁盘上的数据变得不一致。按照默认60秒,MongoDB会周期性的要求操作系统将shared视图中变化的数据刷新到磁盘上,使磁盘上的数据与内存中的数据保存一致,如下图所示:
重新同步private视图并flush到磁盘
当执行完刷新内存中变化的数据到磁盘后,MongoDB会删除掉journal中这个时间点后面的所有写操作,这一点与关系数据库中的checkpoint类似。最后,mongoDB会将shared view与private view重新同步,保持一致性。
mongoDB的journaling日志功能,在2.0版本后是默认启动的,可以在实例mongod启动时,通过启动选项控制;上面提到的步骤中,有一个地方是将写操作周期性批量写到journal日志文件中,这个周期的大小是通过可选启动参数journalCommitInterval来控制的,默认值是100ms。mongoDB经过60s的周期刷新内存中变化的数据到磁盘,这个值通过启动可选参数syncdelay来控制的。这些默认值一般适用于大多数情况,不要轻易更改。通过上面的分析,数据库服务器仍然有100ms的丢失数据的风险,因为journaling日志的写到磁盘上的周期是100ms,假如刚好一批写操还在内存中,没来得及刷到journaling在磁盘上对应的文件上,服务器突然故障,这些在内存中的写操作就会丢失。
mongoDB在启动时,专门初始化一个线程不断循环,用于在一定时间周期内来从defer队列中获取要持久化的数据并写入到磁盘的journal(日志)和mongofile(数据)处,当然因为它不是在用户添加记录时就写到磁盘上,所以按mongodb开发者说,它不会造成性能上的损耗,因为看过代码发现,当进行CUD操作时,记录(Record类型)都被放入到defer队列中以供延时批量(group commit)提交写入。
总之mongoDB利用内存映射的技术来完成这些功能,需要参考unix环境编程中的内存映射MMAP,文件IO等编程知识。
Journaling是MongoDB中非常重要的一项功能,类似于关系数据库中的事务日志。journaling能够使数据库由于其他意外原因故障后快速恢复。
MongoDB实战指南(四):MongoDB的Journaling日志功能的更多相关文章
- 大数据存储:MongoDB实战指南——常见问题解答
锁粒度与并发性能怎么样? 数据库的读写并发性能与锁的粒度息息相关,不管是读操作还是写操作开始运行时,都会请求相应的锁资源,如果请求不到,操作就会被阻塞.读操作请求的是读锁,能够与其它读操作共享,但是当 ...
- MongoDB实战指南(六):MongoDB复制集之复制集概述
1. 复制集概述 数据库总是会遇到各种失败的场景,如网络连接断开.断电等,尽管journaling日志功能也提供了数据恢复的功能,但journaling通常是针对单个节点来说的,只能保证单节点数据的一 ...
- MongoDB实战指南(七):MongoDB复制集之复制集工作机制
http://www.cnblogs.com/longshiyVip/p/5097336.html 概述了复制集,整体上对复制集有了个概念,但是复制集最重要的功能之——自动故障转移是怎么实现的呢?数据 ...
- MongoDB实战指南(二):索引与查询优化
数据库保存记录的机制是建立在文件系统上的,索引也是以文件的形式存储在磁盘上,在数据库中用到最多的索引结构就是B树.尽管索引在数据库领域是不可缺少的,但是对一个表建立过多的索引会带来一些问题,索引的建立 ...
- MongoDB实战指南(五):MongoDB中的聚集分析
聚集操作是对数据进行分析的有效手段.MongoDB主要提供了三种对数据进行分析计算的方式:管道模式聚集分析,MapReduce聚集分析,简单函数和命令的聚集分析. 1. 管道模式进行聚集 这里所说的管 ...
- MongoDB实战指南(三):MongoDB的锁机制
与关系数据库一样,MongoDB也是通过锁机制来保证数据的完整性和一致性,MongoDB利用读写锁来支持并发操作,读锁可以共享写锁具有排他性.当一个读锁存在时,其他读操作也可以用这个读锁:但当一个写锁 ...
- MongoDB实战指南(一):大数据与云计算
1.1 什么大数据 具体来说,大数据技术涉及到数据的创造,存储,获取和分析,大数据的主要特点有下面几个: 数据量大.一个典型的PC机载2000年前后其存储空间可能有10GB,今天facebook一天增 ...
- Mongodb学习笔记四(Mongodb聚合函数)
第四章 Mongodb聚合函数 插入 测试数据 ;j<;j++){ for(var i=1;i<3;i++){ var person={ Name:"jack"+i, ...
- MongoDB学习记录(四) - MongoDB的"增查改删"操作之"改"
更新文档主要有以下几种方法: db.collection.updateOne(filter, update, options) db.collection.updateMany(filter, upd ...
随机推荐
- 也谈一下Activiti工作流节点的自由跳转
最近在搞openwebflow的工作流节点自由跳转功能,在网上看了一些资料,感觉不是很好,总结原因如下: 直接手动调用SqlSession的操作,感觉会漏掉一些重要的初始化操作(如:启动新节点之后加载 ...
- 2) LINQ编程技术内幕--yield return
yield return 使用.NET的状态机生成器 yield return关键词组自动实现IDisposable,使用这个可枚举的地方, 还存在一个隐含的try finally块. 示例代码: c ...
- 【html】【19】高级篇--大事件时间轴
下载: http://sc.chinaz.com/jiaoben/131112181390.htm 其它: http://sc.chinaz.com/tag_jiaoben/shijianzhou.h ...
- WPF 关于XDocument(xml) 的部分操作记录
(1)删除xml文件中的一个结点的方法,有如下两种方式(只有存在数据绑定的情况下才会有第二种情况,否则一般是第一种情况): private void DeletePacsNode() { //从xml ...
- 暑假集训(3)第二弹 -----Jungle Roads(Hdu1301)
问题梗概:自从上次某个acmer来设计了拉格瑞圣岛的交通路线后,岛上的酋长就相当苦恼,他发现,虽然这些修好的公路便利了岛上的 交通,并且让拉格瑞圣岛的旅游业更加兴旺,甚至他们还收到了一笔不小的国际资金 ...
- PHP - 5.4 Array dereferencing 数组值
在5.4之前我们直接获取数组的值得方法如下 <?php $str = 'a;b;c;d'; list($value) = explode(';',$str); echo $value; 结果为: ...
- java basic
//java 声明常量 //final 数据类型 常量名=值; //as: final float PI=3.14f;/ PI=3.14002F //默认浮点为 double //break:跳出多重 ...
- VB winform自动更新 笔记
看网上各种自动更新方法,最后自己找了个比较简单的,在此做个笔记. 服务器上的共享盘里存放生成的可执行文件和XML格式的配置: <?xml version="1.0" enco ...
- 不使用border-radius,实现一个可复用的高度和宽度都自适应的圆角矩形
现在css3支持圆角矩形,但是为了兼容性问题,虽然比较麻烦,但还是有必要了解一下以下方法. 在一个div内,包含8个div,控制这个8个div的height.margin以及border属性值,以达到 ...
- 简单的NHibernate学习笔记
NHibernate是.NET平台下的ORM框架,与ADO.NET一样实现项目中数据库与项目系统的交互. .首先要用NHibernate框架就要有第三方的dll库来作为支持,附上百度云下载地址:(链接 ...