MongoDB 写入和锁定流程

5 replication journaling mongodb locks

我最近读了很多关于 MongoDB 的文章,但我找不到任何明确的材料,即数据如何写入日志和 oplog。

到目前为止我对这个过程的理解是这样的,有错误的地方请指正

  • 客户端连接到 mongod 并执行写入。写操作存储在套接字缓冲区中
  • 当 Mongo 可用时(目前不确定可用意味着什么),数据会写入日志吗?
  • mongoDB 文档随后表示,每 60 秒写入一次就会从日志刷新到磁盘上。由此我只能假设这意味着写入主数据库和操作日志。如果是这种情况,如何写入早于 60 秒同步间隔?
  • 一段时间后,辅助节点从主节点或其同步源吸收数据并更新其操作日志和数据库。对于这种情况到底何时发生以及是什么延迟了似乎非常模糊。

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

最后,我有点困惑在这个过程中的哪些点上创建了写锁。这是仅在数据库和 oplog 更新时发生还是在其他时间发生?

感谢任何可以阐明这一点或向我指出一些阅读材料的人。

西蒙

Mar*_*erg 4

据我了解,这是发生的事情。我简化了一点,但应该清楚它是如何工作的。

  1. 客户端连接到 mongo。到目前为止,还没有完成任何写入操作,也没有断开任何连接,因为这实际上取决于写入问题现在发生的情况。假设我们使用(在撰写本文时)默认的“已确认”。
  2. 客户端发送它的写操作。这是我真的不确定的地方。在此步骤或下一步之后,确认会发送给驱动程序。
  3. 写操作通过查询优化器运行。正是在此处发送确认,因为在确认的写入问题中,您可能会返回重复键错误。这可能是在最后一步中检查过的。如果我打赌的话,我会说是在这之后。
  4. 然后,查询优化器的输出将应用于内存中的数据,实际上是内存映射数据文件的数据、内存映射 oplog 和日志的内存映射文件。从该存储器映射部分回答查询,或者将相应的数据映射到存储器以回答查询。如果存在的话,oplog 也会从内存中读取。
  5. 一般情况下,每 100 毫秒日志就会同步到磁盘。精确值由许多因素决定,其中之一是journalCommitInterval配置参数。如果您有记录的写入问题,驱动程序现在就会收到通知。
  6. syncDelay秒,内存映射文件的当前状态都会同步到磁盘我认为日志被截断为尚未应用于数据的条目,但我不太确定这一点,因为它基本上永远不会发生日志中的数据尚未应用于当前数据。

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

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

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

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

希望这可以帮助。