MongoDB:批量操作是作为整体写入oplog的吗?

时间:2015-08-22 13:30:07

标签: mongodb mongodb-query

当我在MongoDB 3中发出有序批量操作时,整个批量操作是否写入oplog,以便在服务器崩溃后可以作为一个整体重放?

这个问题的基本原理如下:

我知道没有真正的交易,但我可以使用$isolated关键字来获得一些读取一致性(在某些情况下)。 除了良好的模式设计之外,让我们假设我必须一次性更新可能不同的集合中的多个文档,这将是SQL中的一个事务。我不关心数据在任何时刻处于不一致状态,但我确实要求数据最终 。因此,虽然我可能不关心操作期间的错误和丢失回滚,但我要求在某些时候完全不执行执行更新序列,为了让它们在批量操作过程中遇到意外的服务器故障或停机(因为,例如,随机的CoreOS更新)。

1 个答案:

答案 0 :(得分:4)

我将以一般警告进入这一点,我承认我甚至没有看过结果,但基本原则从一开始就对我有用。

这里你需要考虑的是“一般调用中提供的”很好的语法糖“实际发生的事情”。这意味着什么是基本上看你正在调用的操作的“命令形式”实际上做了什么。在这种情况下"update"

因此,如果您已查看该链接,请考虑以下"Bulk"更新表单:

var bulk = db.collection.initializeOrdedBulkOp();

bulk.find({ "_id": 1 }).updateOne({ "$set": { "a": 1 } });
bulk.find({ "_id": 2 }).updateOne({ "$set": { "b": 2 } });

bulk.execute();

现在您已经知道这是以一个请求发送到服务器的,但您可能不会考虑的是“引擎盖下”的实际“请求”实际上是这样的:

db.runCommand({
    "update": "collection",
    "updates": [
        { "q": { "_id": 1 }, "u": { "$set": { "a": 1 } } },
        { "q": { "_id": 2 }, "u": { "$set": { "b": 2 } } }
    ],
    "ordered": true
})

因此,按照理由,您在“更新”操作下实际看到的内容实际上就像(从完整输出缩写为查询):

{ "q": { "_id": 1 }, "u": { "$set": { "a": 1 } } }
{ "q": { "_id": 2 }, "u": { "$set": { "b": 2 } } }

因此,这意味着具有相关命令的每个操作都在oplog中用于“重放”复制和/或您可能执行的其他操作,例如专门“重放”oplog条目。

我确信这就是实际发生的事情,甚至没有看,因为我知道驱动程序如何实现实际调用,并且每次调用以这种方式保存在oplog中是有道理的。

因此“作为一个整体”,然后没有。这些不是“交易”,即使它们的提交和返回都在单一的请求中,也始终是不同的操作。但它们是一种单一的操作,因此不会也不应该被记录下来。