69

MongoDB 的“丢失数据”批评在多大程度上仍然有效?我指的是以下内容

1. MongoDB默认以不安全的方式发出写入以赢得基准测试

如果您不发出 getLastError(),MongoDB 不会等待来自数据库的任何确认该命令已处理。这至少引入了两类问题:

  • 在并发环境(连接池等)中,您可能会在写入“完成”后出现后续读取失败;没有障碍条件可以知道数据库将在什么时候识别写入承诺
  • 由于在各个地方排队,TCP 缓冲区中未完成的事情等,任何未知数量的保存操作都可能被丢弃在地板上,当您的 db 连接丢失被 KILL'd 或 segfault,硬件崩溃时,您可以命名它

2. MongoDB 会以许多令人吃惊的方式丢失数据

以下是我们亲身经历的记录丢失的方式列表:

  1. 他们只是有时消失了。原因不明。
  2. 损坏数据库的恢复不成功,预事务日志。
  3. master 和 slave 之间的复制在 oplogs 中有间隙,导致 slave 丢失 master 拥有的记录。是的,没有校验和,是的,复制状态有从属当前
  4. 复制有时会停止,没有错误。监控您的复制状态!

...[其他批评]

如果仍然有效,这些批评在某种程度上会令人担忧。文章主要参考 v1.6 和 v1.8,但此后 v2 已经发布。文章中讨论的缺点在当前版本中是否仍然突出?

4

4 回答 4

58

上下文注意事项:

这个问题是在 2012 年提出的,但直到今天仍然看到流量和投票。最初的答案是专门驳斥在问题发生时流行的特定帖子。自从写下这个答案以来,事情已经发生了巨大的变化(并且还在继续变化)。与 2012 年相比,MongoDB 无疑变得更加耐用和可靠,即使是像基本日志这样的东西也相对较新。我对这个答案投了反对票和评论,因为人们觉得我没有解决名义问题(不是细节)的当前(对于当前的给定值)一般答案:“丢失的数据批评仍然有效吗?”。我试图在下面的更新中澄清,但这个问题基本上没有完美的答案,这取决于你的观点,你的期望是什么,你使用的是什么版本,

原答案:

MongoDB 首席技术官兼联合创始人艾略特·霍洛维茨(Eliot Horowitz)在此处逐点揭穿了该特定帖子:

http://news.ycombinator.com/item?id=3202959

这里也有一个很好的总结:

http://www.betabeat.com/2011/11/10/the-trolls-come-out-for-10gen/

简短的版本是,看起来这基本上是有人在吸引注意力(成功地),没有确凿的证据或佐证。过去曾发生过真正的事件,随着产品的发展(例如,参见 1.8 中对日志的介绍)或发现并修复了更具体的错误,这些事件已得到处理。

免责声明:我确实为 MongoDB(以前的 10gen)工作,并且喜欢 philnate 来到这里并首先独立反驳这一事实 - 这可能比其他任何东西都更能说明产品:)

更新:2013 年 8 月 19 日

我最近在这个答案上看到了很多活动,我认为这与SERVER-10478中的错误公告有关- 这肯定是一个边缘案例,但我仍然建议任何使用大文档分片的人尽快升级到 v2.2.6 和 v2.4.6,其中包含此问题的修复程序。

更新:2017 年 3 月 24 日

我不再为 MongoDB 工作,但仍然支持这个答案。鉴于此答案继续获得(和否决)选票并收到很多意见,我想在这篇文章中指出人们,它显示了自提出这个问题以来 MongoDB 取得的进展。该数据库现在通过了Jepsen测试,并将测试集成到其构建过程中,还有很多更成熟的系统没有通过。2017 年仍在敲打数据丢失鼓的人真的没有受到关注。

更新:2020 年 5 月 24 日

Jepsen重新分析了 MongoDB 4.2.6,因为 MongoDB 现在提供“完整的 ACID 事务”,虽然它在某些方面变得相当技术性,但如果您担心 MongoDB 中的数据丢失,我强烈建议您阅读这篇文章(我建议您查看您使用 Jepsen 测试的任何数据库,您可能会对它们的弱点感到惊讶)。该报告总结了默认读写问题的弱点,讨论了具有适当读写问题的非事务读写的可靠性,解决了文档中的缺陷,然后提供了有关测试新问题时遇到的问题的重要细节ACID 事务(以及相关的读/写问题)。

那么,您仍然可以使用 MongoDB 丢失数据吗?是的,尤其是默认设置,但大多数数据库都是如此。当这个问题被回答时,事情比他们回来时要好得多,并且这些功能具有更高的可靠性和耐用性,而且它们似乎有效(交易除外)。我的建议是了解您操作配置的限制,然后确定您的产品/业务/用例是否可以接受数据丢失风险。

于 2012-05-14T11:33:53.913 回答
50

我不能说每一个案例,只说我自己的。但是,与其他答案不同,我不为 Mongo 或其竞争对手工作,我在使用 MongoDB 时丢失了数据,并且使用了 Mongo 大约十年,所以就这样吧。

2010

这是我第一次开始使用 Mongo 时,当时对 Mongo 的主要批评是:

  • 据称,Mongo 的稳定版本存在重大的数据丢失错误,这些错误并未向用户明确说明。例如,在 1.8 之前的非集群配置可能会丢失数据。Mongo 记录了这一点,但没有达到稳定版本数据库中数据丢失错误的程度。

该批评的主要辩护是:

  • 用户被告知了这种危险,尽管没有那么明确。用户应该在开始之前阅读所有文档。

在我自己的情况下,我在单个服务器配置中使用 1.7,但意识到风险。我关闭了数据库进行备份。关闭数据库本身的行为丢失了我的数据,10gen 协助(免费)但无法恢复数据。

2013

后来,在 2013 年,一项研究表明MongoDB 的默认设置会导致网络分区期间确认写入的大量丢失。

同样在 2013 年 Mongo官方生产节点 Mongo 驱动程序包装并丢弃了所有错误

2014

从那以后,在 2014 年,稳定的 MongoDB 驱动程序中的一个完全不同的错误让我和许多其他用户陷入了困境。

2016 年(以及 2020 年再次)

2016年,Meteor 项目遇到了 MongoDB 查询并不总是返回所有匹配文档的问题

后来 MongoDB 的默认监听所有接口且没有设置管理员密码的策略对许多用户来说也很糟糕。我们在 20 年前(可能更早,但我当时不在技术领域)就知道默认监听所有端口是一个坏主意,这就是其他软件避免这种情况的原因。

2020 年更新:Meow 攻击现在会自动破坏具有 Mongo 旧网络默认设置的数据库。

2020

Jepsen 评估了 MongoDB 4.2.6并得出结论:

即使在最高级别的读写问题上,MongoDB 4.2.6 也未能保留快照隔离。相反,Jepsen 观察到读取偏差、循环信息流、重复写入和内部一致性违规。弱默认值意味着事务可能会丢失写入并允许脏读,甚至会降低数据库和集合级别请求的安全级别。

结论

多年来,普遍的、反复的观察表明,Mongo 有不安全的默认值来赢得性能基准。Mongo 通常会回应说,用户应该通过阅读所有相关文档来了解这些内容,并且可以在需要时使用选择使用安全选项。

截至 2020 年,我觉得 MongoDB 现在实际上是一个更稳定的产品,只是通过时间和投资,但是我永远不会相信该公司十年来使用我们的数据进行 beta 测试,如果再次丢失数据我一点也不感到惊讶状况被揭露。我使用 Postgres JSONB、FoundationDB 和 RethinkDB 作为结构化数据存储,它们可能是有效的替代方案。

在此处输入图像描述

于 2013-08-16T09:19:33.267 回答
17

截至 2017 年 2 月,Jepsen 对 MongoDB 的最新分析表明,在 MongoDB 3.2.11 和 3.4.0-rc4 之前的所有 MongoDB 版本中都可能发生数据丢失

因此,在撰写问题时(2012 年),答案应该是肯定的,这些批评从理论角度来看是有效的。但看起来客户并不关心这个理论。正如RethinkDB 失败所表明的,正确性并不重要。唯一重要的是上市时间。很伤心。

截至 2018 年 10 月,在 MongoDB 3.4 上 - 这仍然是一个问题。

于 2017-07-24T20:33:18.450 回答
12

在最近的版本中从未听说过那些严重的问题。你需要考虑的是,MongoDB 作为关系系统在后面没有十年的发展。此外,MongoDB 可能根本没有提供那么多功能来避免数据丢失。但即使使用关系系统,您也无法确定您永远不会丢失任何数据。这在很大程度上取决于您的系统配置(因此使用复制和手动数据备份您应该非常安全)。

作为避免早期版本中的 Beta 错误或错误的一般准则,请避免在生产中使用新版本(这是 debian 在服务器中如此受欢迎的原因)。如果 MongoDB 会(一直)遭受如此严重的问题,那么用户列表会更小:https ://www.mongodb.com/community/deployments 另外我不太相信这个 pastebin 消息,为什么要匿名发布?这个人公司是不是羞于告诉他们使用了mongodb,他们害怕10gen?这些错误报告的链接在哪里(或者 10gen 是否从 JIRA 中删除了它们?)

因此,让我们简短地谈谈这些要点:

  1. 是的,MongoDB 在“即发即弃”模式下正常运行。但是您可以使用以下几个选项修改此行为: https ://docs.mongodb.com/manual/reference/command/getLastError/#dbcmd.getLastError 。因此,仅因为 MongoDB 默认使用它,并不意味着您不能根据需要更改它。但是,如果您没有在应用程序中触发并忘记,那么您需要降低性能,因为您正在添加往返。

    更新:从 2.6 版开始,命令insert, update, save,remove默认情况下会确认写入。

  2. 从来没有听说过这样的问题,除了那些导致自己失败的问题......但关系系统也可能发生这种情况。我想这一点只谈论主从复制。副本集永远不会稳定。来自网络的一些链接,其中其他 dbms 也因故障而导致数据丢失:http: //blog.lastinfirstout.net/2010/04/bit-by-bug-data-loss-running-oracle-on.html http: //dbaspot.com/oracle-server/430465-parallel-cause-data-lost-another-oracle-bug.html http://bugs.mysql.com/bug.php?id=18014 (那些发布的链接是' t 有利于给定系统,或者应该暗示其他任何事情,而不是表明其他系统中也存在可能导致数据丢失的错误。)

  3. 是的,实际上在实例级别有锁定,我不认为在分片环境中这是一个全局的,我认为这将在每个分片单独的实例级别,因为没有必要锁定其他实例,因为没有一致性检查需要。即将发布的 2.2 版将锁定在 DB 级别,Collection Level 的票证可能还会存在扩展或文档(https://jira.mongodb.org/browse/SERVER-4328)。但是更深层次的锁定可能会影响 MongoDB 的实际性能,因为锁定管理成本很高。

  4. 移动块不应该引起太多问题,因为重新平衡应该从每个节点中取出一些块并将它们移动到新节点。它永远不会导致块的 ping/pong,也不会仅仅因为一两个块的差异而开始重新平衡。当您的分片键选择错误时,可能会出现问题。因此,您最终可能会将所有新条目插入一个节点而不是全部。因此,您会更频繁地看到可能导致问题的重新平衡,但这不是由于 mongo 而不是您选择不当的 shardkey。

  5. 不能评论这个

  6. 不是 100% 肯定,但我认为 Replicasets 是在 1.6 中引入的,所以如前所述,永远不要使用最新版本进行生产,除非你可以忍受数据丢失。与每个新功能一样,都有可能出现错误。即使是广泛的测试也可能无法揭示所有问题。再一次,为了上帝的缘故,总是运行一些手动备份,除非你可以忍受数据丢失。

  7. 无法对此发表评论。但实际上软件可能包含严重的错误。许多游戏也遇到了这些问题,并且香蕉软件在其他领域也广为人知。无法评论具体的事情,因为这是在我的 MongoDB 时代之前。

  8. 复制可能会导致此类问题。根据复制策略,这可能是一个问题,另一个系统可能更适合。但是如果没有真正真正的写入密集型工作负载,您可能不会遇到此类问题。事实上,让 3 个副本轮询来自一个主节点的更改可能会有问题。您可以通过添加更多分片来解决问题。

作为一般性结论:是的,可能存在这些问题,但是 MongoDB 在这个方向上做了很多工作,而且我怀疑其他 DBMS 本身从来没有遇到过这个或其他问题。就拿传统的关系数据库来说,那些可以很好地扩展到网络规模的系统就不需要像 MongoDB、HBase 等系统了。您无法获得满足所有需求的系统。所以你必须忍受一个人的缺点,或者尝试建立一个由多个人组成的组合系统来获得你需要的东西。

免责声明:我不隶属于 MongoDB 或 10gen,我只是与 MongoDB 合作并发表我的看法。

于 2012-05-12T20:12:19.243 回答