编辑:我在 2011 年 Dwight 在 MongoSF 上的演讲的原始链接现在已经死了,但是Ben Becker 在2012 年的演讲中有类似的内容。
以防万一它在某个时候也停止工作,我将简要概述原始 MMAP 存储引擎中的日志是如何工作的,但应该注意的是,随着可插拔存储引擎模型(MongoDB 3.0 及更高版本)的出现,这现在完全取决于您使用的存储引擎(可能还有选项) - 所以请检查。
回到原始 (MMAP) 存储引擎日志。在非常基本的级别上,日志包含一系列排队操作,并且所有操作都在发生时写入其中 - 基本上是仅追加到磁盘的顺序写入。
一旦这些操作被应用并刷新到磁盘,它们就不再需要在日志中并且可以被老化。从这个意义上说,日志基本上就像一个用于写操作的循环缓冲区。
在内部,日志中的操作存储在“提交组”中——一组写操作的逻辑组。一旦一个操作在一个完整的提交组中,它可以被认为是作为日志的一部分同步到磁盘(j:true
例如,将满足写关注)。不干净的关闭后,mongod
将尝试应用之前未刷新到磁盘的所有完整提交组,不完整的提交组将被丢弃。
日志中的操作不是您将在oplog中看到的,而是一组更简单的文件、偏移量(本质上是磁盘位置)和要在该位置写入的数据。这允许有效地重放数据,并为日志提供紧凑的格式,但会使内容看起来像大多数人的胡言乱语(与上述基本上可以作为 JSON 文档读取的 oplog 相反)。这基本上回答了提出的问题之一——它不知道数据库文件的内容和要对其进行的更改,它甚至更简单——它基本上只知道去磁盘位置 X 并写入数据 Y,而已。
日志的预写顺序性质意味着它非常适合旋转磁盘,顺序访问模式通常与 MMAP 数据访问模式不一致(尽管不一定与其他引擎的访问模式)。因此,有时将日志放在自己的磁盘或分区上以减少 IO 争用是个好主意。