0

这个 Mongo 页面解释了 $snapshop 命令的作用,但是有人可以解释为什么这会有所帮助,或者默认禁用是否明智?

我们在 Rails 3.2.12 上使用 MongoMapper,MM 似乎在每个查询上都启用了快照。

4

2 回答 2

1

由此,我们应该假设,如果存在并行写入和读取文档的可能性,那么我们不应该关闭 $snapshot 吗?或者,更准确地说,最坏的情况是什么?那个用户得到了一份过时的文件?

不,不是过时的文件。但可能同一个文档两次,在应用更新之前(当时不是陈旧的)和应用更新之后。

仅当更新更改文档的大小时才会发生这种情况,因此必须将其物理移动到存储位置。就地更新不会发生这种情况。如果你将一些大的东西放入一个数组中,就会发生这种情况。

另请注意,根据您对此的看法,您可以将文档的第一个版本称为“陈旧”(在查询完成时),但同样适用于所有其他文档:您得到的版本是准确的在您的查询提取此单个文档时。不一定在整个查询中全局一致。

最后,即使打开了 $snapshot,您仍然无法保证不会删除已删除的文档并获取所有新插入的文档。显然,它也不适用于分片。

从好的方面来说,您获得的文档(打开或关闭快照)始终是内部一致的:您总是获得一个曾经存在的版本,而不是更新中间的奇怪状态。

假设一个查询返回一个用户及其所有关联的小部件。通过禁用 $snapshot,相同的查询将返回播放器文档两次……这意味着返回数组可能包含两个对象而不是一个?

如果它们存储在两个集合中,则相同的查询不能返回“一个用户和他的所有小部件”。MongoDB 中没有连接。

如果小部件嵌入到用户对象中,那么它们将与用户一起返回,并且始终表示一致的组合。

这里可能发生的情况是,如果您查询具有小部件 A 或 Z 的所有用户的列表,并且您将具有小部件 A 的用户更新为也具有小部件 Z(这会移动文档,因为它现在已经增长)您可以使用小部件 A 获取用户,然后使用小部件 A 和 Z 第二次获取用户。

如果您打开快照,那将不会发生(除非您使用分片,否则快照显然不起作用)。但是您仍然可以获得同时被删除的用户,或者在查询运行时无法获得正在插入的所有用户。

于 2013-05-19T23:00:41.227 回答
0

扫描 MongoMapper 和 MongoClient 代码,看起来 $snapshot 默认是关闭的。检查您的代码是否作为选项传递给某处的查询。

于 2013-05-20T03:39:50.877 回答