MongoDB写入和锁定进程



我最近读了很多关于MongoDB的文章,但有一个主题我找不到任何明确的材料,那就是如何将数据写入日志和操作日志。

到目前为止,这就是我对这个过程的理解,请纠正我错误的

  • 客户端连接到mongod并执行写入操作。写入存储在套接字缓冲区中
  • 当Mongo可用时(不确定此时可用意味着什么),数据会被写入日志
  • mongoDB文档说,每60秒的写入都会从日志中刷新到磁盘上。我只能假设这意味着写入主日志和操作日志。如果是这种情况,如何在60秒同步间隔之前写入
  • 一段时间后,辅助设备从主设备或其同步源获取数据,并更新其操作日志和数据库。关于这种情况究竟何时发生以及是什么原因造成的延误,似乎非常模糊

我还想知道,如果日志记录被禁用(我知道这是一个非常糟糕的主意),oplog和数据库在什么时候更新?

最后,我有点困惑,在这个过程中,写锁是在什么时候创建的。这只是在数据库和操作日志更新时,还是在其他时间?

感谢任何能对此有所了解或为我介绍一些阅读材料的人。

Simon

以下是我所了解的情况。我简化了一点,但应该清楚它是如何工作的。

  1. 客户端连接到mongo。到目前为止,还没有完成任何写作,也没有破坏任何联系,因为这实际上取决于写作关注点现在发生了什么。让我们假设(在撰写本文时)默认为"已确认"
  2. 客户端发送其写入操作。这是我真的不确定的地方。无论是在该步骤之后还是在下一步骤之后,都会向驾驶员发送确认
  3. 写入操作通过查询优化器运行。正是在这里发送确认,因为在已确认的写入问题中,您可能会返回一个重复的密钥错误。这可能是在最后一步中检查过的。如果我敢打赌的话,我会说是在这次之后
  4. 查询优化器的输出随后应用于内存中的数据实际上应用于内存映射数据文件的数据、内存映射操作日志和日志的内存映射文件。从这个内存映射部分回答查询,或者将相应的数据映射到内存以回答查询。操作日志也会从内存中读取(如果存在)
  5. 通常每100毫秒,日志就会同步到磁盘。精确的值由许多因素决定,其中一个因素是journalCommitInterval配置参数。如果您有日志记录的书面问题,将立即通知驾驶员
  6. 每隔syncDelay秒,内存映射文件的当前状态就会同步到磁盘我认为日志会被截断为尚未应用于数据的条目,但我对此不太确定,因为日志中的数据基本上不会应用于当前数据

如果您仔细阅读过,您会注意到,在oplog通过查询优化器运行并应用于映射到内存中的文件时,数据就已经准备好了。当oplog条目由其中一个辅助设备提取时,它会立即应用于内存映射文件的数据,并以与主设备相同的方式在磁盘中同步。

需要注意的是:只要将相对较小的数据写入日志,就相当安全。如果一个节点在两次同步数据文件之间发生故障,则数据文件和操作日志都可以从数据文件和日志中的上次状态恢复。一般来说,您可以拥有的最大数据丢失是在最后一次提交后记录到日志中的操作,中位数为50ms。

至于锁。如果您写得很仔细,在将数据同步到磁盘时,不会对数据库级别施加锁。可以创建写锁,以确保在任何给定时间点只有一个线程修改给定文档。还有其他可能的写锁,但一般来说,它们应该相当罕见。

文件系统层上的写锁创建一次,尽管只是隐式的iirc。在应用程序启动期间,会在dbpath的根目录中创建一个锁定文件。当存在有效锁时,任何其他mongod实例都将拒绝对这些数据文件执行任何操作。你也不应该;)

希望这能有所帮助。

最新更新