【问题标题】:Why doesn't MongoDB use fsync()?为什么 MongoDB 不使用 fsync()?
【发布时间】:2010-09-17 15:06:02
【问题描述】:

所以我做了一些研究,发现 MongoDB 不做 fsync(),这意味着当你告诉数据库写一些东西时,数据库可能会告诉你它是写的,虽然它不是。这不违反 CRUD 吗?

如果我是对的,有什么好的理由吗?

【问题讨论】:

  • MongoDB 实际上不会告诉您何时写入数据。单服务器持久性计划在即将发布的版本中发布(我相信是 1.8)。
  • 我认为任何数据库都不会真正违反 CRUD(创建/读取/更新/删除),除非它是只读数据库。假设您的意思是下面接受的答案中假设的 ACID?

标签: mongodb database nosql


【解决方案1】:

原因是性能。不必在每次更改时写入磁盘,M​​ongoDB 可以更快地处理更新。

MongoDB 会告诉您更新何时交付到服务器,而不是更新何时写入,您可以在Verifying Propagation of Writes with getLastError 上的文档中阅读:

注意:当数据已经传送到 [the] 服务器时,当前实现会返回。未来的版本将提供更多交付选项,而不是服务器上的物理 fsync。

这违背了ACID,更具体地说,违背了代表耐用性的D:

持久性 [保证]一旦通知用户事务成功,事务不会丢失,事务的数据更改将在系统故障后继续存在,并且所有完整性约束都已满足,因此 DBMS 不需要撤销交易。

ACID 属性主要适用于传统的 RDBMS 系统。包括 MongoDB 在内的 NoSQL 系统放弃了一种或多种 ACID 属性,以实现更好的可扩展性。在 MongoDB 的案例中,牺牲了耐用性,以便在处理大量更新时获得更好的性能。


MongoDB 和 ACID

大多数 ACID 属性是事务级别的保证。事务通常是一组查询,应被视为一个单元。 MongoDB 没有事务的概念,同样适用于performance reasons。因此大多数 ACID 属性不适用于 MongoDB。

A——原子性表明事务要么成功要么失败。不允许部分成功;如果部分事务失败,则应回滚整个事务。 MongoDB 在文档级别支持atomic operations,但不支持“事务”级别。

C——一致性部分指的是原子性,但也包括参照完整性。关系数据库负责确保所有外键引用都是有效的。 MongoDB 没有外键的概念,所以这个 ACID 属性不适用。

I — 隔离声明不允许两个并发事务相互干扰;如果两个事务尝试修改相同的数据,则第二个事务必须等待第一个事务完成。为此,数据库将锁定数据。 MongoDB 没有锁定的概念,因此不支持多个操作的隔离1)。单个操作是隔离的。

D — 上面描述了耐用性。就 ACID-ic 持久性而言,MongoDB 不支持真正的持久性。

现在,您可能认为 MongoDB 与 RDBMS 系统相比毫无用处,因为它缺乏事务和大多数 ACID 保证。但是,事务存在的部分原因是关系数据库需要将某些数据视为单个实体,而这些数据已被规范化为多个表

MongoDB 允许您将数据存储为单个实体。在大多数情况下,这消除了对外键和参照完整性的需求。您也不需要多查询事务,因为您不需要多个表来更新单个实体。大多数时候你只需要更新一个文档,而这些操作在 MongoDB 中是原子的。

1) 根据first comment on this pagedb.eval() 为多个操作提供隔离。但是,根据the documentation,您通常希望避免使用db.eval()

【讨论】:

  • 好的,所以数据库数据每 60 秒满足 ACID 中的 D,因为 fsync() 每分钟执行一次,将内存中的所有数据保存到磁盘,对吧?
  • @ajsie:技术上不是。为了满足 D,数据必须在数据库响应成功时写入磁盘。但是 MongoDB 那时仅将数据写入内存,因此数据还不是“持久”的。由于 fsync(),它在最多 60 秒后持久的。
  • @Niels van der Rest:MongoDB 只是违反了 ACID 中的 D 还是还有其他违规行为?
  • @Niels:但是如果我必须进行跨越 2 个文档的交易(例如转账),那么我认为使用 MongoDB 是不可靠的。你说 MongoDB 违反了所有的 ACID 属性。你知道 CouchDB 违反了哪些吗?
  • @ajsie:我对 CouchDB 不是很熟悉,但我相信它比 MongoDB 有更好的 ACID 支持。可能是一个新问题的好材料:)
【解决方案2】:

这有关系吗?

durability: added occasinal file sync
default: sync every 60 seconds, confiruable with syncdelay

http://github.com/mongodb/mongo/commit/c44bff08fd95616302a73e92b48b2853c1fd948d

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 2012-09-21
    • 2011-05-16
    • 2021-09-21
    • 2023-03-07
    • 2021-05-06
    • 1970-01-01
    • 2013-03-24
    • 2015-08-18
    相关资源
    最近更新 更多