MongoDB:批量操作是否作为一个整体写入oplog?

MongoDB:批量操作是否作为一个整体写入oplog?,mongodb,mongodb-query,Mongodb,Mongodb Query,当我在MongoDB 3中发布一个有序的批量操作时,批量操作是否作为一个整体写入oplog,以便在服务器崩溃后可以作为一个整体重放 这个问题的理由如下: 我知道没有真正的事务,但我可以使用$isolated关键字来实现某种读取一致性(在某些情况下)。 除了良好的模式设计与否,让我们假设我必须一次性更新可能不同集合中的多个文档,这在SQL中是一个事务。我不关心数据在任何时候处于不一致的状态,但是我确实要求数据最终保持一致。因此,虽然我可能不关心操作过程中的错误和丢失回滚,但我要求更新序列完全执行或

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

这个问题的理由如下:

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

我将带着一般性的警告进入这篇文章,我承认我甚至没有看过结果,但基本原则从一开始就对我有效

你需要考虑的是“一般的语法糖”下的实际情况。这意味着基本上看一下您调用的操作的“命令形式”实际上做了什么。在这种情况下

这样,如果您已经查看了该链接,请考虑以下更新形式:

var bulk=db.collection.initializeOrdedBulkOp();
bulk.find({“\u id”:1}).updateOne({“$set”:{“a”:1}});
bulk.find({“\u id”:2}).updateOne({“$set”:{“b”:2}});
bulk.execute();
现在,您已经知道这是作为一个请求发送到服务器的,但您可能没有考虑的是,“在引擎盖下”发出的实际“请求”实际上是:

db.runCommand({
“更新”:“收集”,
“更新”:[
{“q”:{“{u id”:1},“u”:{“$set”:{“a”:1}}},
{“q”:{“_id”:2},“u”:{“$set”:{“b”:2}}
],
“有序”:正确
})
因此,您在“update”操作下的日志中实际看到的内容实际上类似于(从完整输出缩写为仅查询):

{“q”:{u id:1},“u”:{“$set”:{“a”:1}}
{“q”:{“_id”:2},“u”:{“$set”:{“b”:2}}
因此,这意味着带有相关命令的每个操作都位于oplog中,用于在复制和/或可能执行的其他操作(例如专门“重放”oplog条目)上进行“重放”

我甚至不看一眼就可以确定这就是实际发生的事情,因为我知道驱动程序是如何实现实际调用的,而且每个调用都以这种方式保存在oplog中是有意义的


因此,“作为一个整体”,则不是。这些不是“事务”,并且始终是不同的操作,即使它们的提交和返回在单个请求中。但是它们不是一个单数运算,因此不会也不应该被记录为单数运算。

不确定我是否正确,但你的结论似乎与你上面所说的相矛盾;再说一遍,也许我只是愚蠢地问。因此,不同的方法是:是在第一个更新工作开始之前将单个更新写入oplog,还是系统可能处于一种状态,即不是所有的单个更新都“注册”,因此从技术上讲,任何数量的更新都可能丢失?@sunside我想这很清楚。作为“一个请求”和一个响应发送,但“提交”作为“单独的操作”。因此,每个更新实际上应该是一个单独的oplog条目,而不是一个“批”操作。“从技术上讲”,我还声明“不是事务”,因此无法“保证”(如果您没有得到确认响应,并且服务器在过程中崩溃)批处理中提交的所有请求都是“全部”提交的。这就是MongoDB的基本工作原理。我得到的这个(我想),我只是想知道内部行为基本上是不是,
take first,register first,perform first,take next,register,perform,…
或者更多类似于
register all,perform first,perform next,
。似乎你同时更新了你的评论。你知道除了两阶段提交之外,还有什么琐碎的解决方案吗?@sunside我基本上是说,它不是那样的。将“无序”操作视为批处理请求。这基本上意味着批处理中的所有操作都是以“任意顺序”应用的,因此意味着在不同的“线程”上进行“单独”操作(从内部来说)。在这两种情况下,也有“错误”的反应要考虑,在那里只适用于“应用”那些运行的操作,而不是那些错误的操作。“重放”不能导致修改或插入的东西没有意义吗?@sunside好吧,这是解决“那个”问题的基本程序。例如,标记“正在进行”,做一些事情,回来并标记“完成”。这里没有“交易”。只有我们熊。