本文翻译自 write concern。
注意,本文内容适用于MongoDB Manual 3.0.2及以上版本。
What's write concern
所谓的写关注就是当向客户端报告写操作的成功执行时,MongoDB提供的保证。通过提供不同级别的写关注来解决应用的具体需求。
Considerations
Default Write Concern
mongo shell和MongoDB驱动使用acknowledged作为默认写关注级别。
Read Isolation
注:读与写如何隔离?写与写如何隔离?
在将这些修改提交至磁盘之前,MongoDB允许客户端读取刚插入或修改的文档,不管写关注的级别或日志(journaling)配置。其结果是,应用可以观察到两类行为:
- 对于有多个并发读取者和写入者的系统来说,在写操作返回之前,MongoDB允许客户端读取写操作的结果。
- 如果在提交数据至日志(journal)之前mongod进程终止了,那么即使写操作成功返回了,查询仍可能读取到 在mongod重启后 并不存在的数据。
其他数据库系统称这些 隔离语义(isolation semantics) 为read uncommitted。对于所有的插入和更新,MongoDB以隔离方式修改每一个文档:客户端从不会看到中间状态的文档。对于多文档操作来说,MongoDB并未提供多文档事物或隔离。
当以单机方式(standalone)方式部署的mongod从使用journaled写关注的写操作中返回时,数据就完全提交至磁盘了,重启mongod后它们就可用了。
对于副本集,只有在 在副本集的大部分投票节点上写操作被复制且提交数据至日志 之后,写操作才是持久的。MongoDB会定期(regularly)提交数据至日志,不管journaled写关注:使用commitIntervalMs去控制mongod多长时间提交一次数据。
Timeouts
客户端可以设置一个wtimeout值,作为replica acknowledged写关注的一部分。如果在指定的时间间隔内写关注未被满足,当前操作就会返回错误,即使写关注最终成功完成。
在wtimeout间隔过期之前,MongoDB不会回滚或撤消已做出的修改。
Write Concern Levels
MongoDB有下面这些概念性的写关注等级,由弱到强:
(注:下面这些只是逻辑概念上的写关注级别,并非配置write concern时刚好有这几个配置枚举值可选。实际上写关注包含两个方面,分别对应两个配置项:w和j,需要组合这两个配置项来实现下面这些写关注级别。具体请看Write Concern Reference。)
unacknowledged
MongoDB不会告知客户端写操作已收到。unacknowledged类似于error ignored。然而,驱动程序在可能的时候会试图接收并处理网络错误。但驱动检测网络错误的能力有赖于系统的网络设置。
在Default Write Concern Change勾画出的发布(注:此版本已发布于2012.11)之前,unacknowledged就是默认写关注。
acknowledged
acknowledged 也叫 receipt acknowledged。mongod会告知客户端已收到写操作,并且已将改变应用于数据的内存视图。acknowledged 写关注(write concern)允许客户端捕获网络(network)、重复键(duplicate key)和其他错误。但acknowledged 写关注并不会确认写操作已经被持久化到磁盘系统。
从Default Write Concern Change勾画出的驱动发布(注:此版本已发布于2012.11)开始,MongoDB将默认使用acknowledged写关注。
journaled
MongoDB仅在将数据提交到journal后才告知客户端。(告知客户端什么信息呢?)这种写关注会确保在关机或电力中断后MongoDB能够恢复数据。
你必须启用journaling以使用这种写关注。
使用这种写关注,写操作必须等到下一次日志提交(journal commit)才能返回。为了降低操作延迟,MongoDB也增加了它提交数据至日志(journal)的频率。参考commitIntervalMs文档以获取更多信息。
注意:
如果在副本集中需要journaled写关注,只需要写操作在主节点上完成日志提交就行了,不用考虑replica acknowledged写关注。(journaled写关注只是一种逻辑上的写关注级别,实际并没有这个配置项值,组合w和j两个配置项才能实现用户期望的写关注。)
replica acknowledged
关于写关注,副本集(relica set)提出了额外的考虑因素。默认写关注仅要求来自主节点(the primary)的确认(acknowledgement)。
使用这种写关注,你能够确保写操作被传播至副本集中的额外成员,即部分从节点(the secondary)。参考**Write Concern for Replica Sets **文档以获取更多信息。
注意:
如果在副本集中需要journaled写关注,只需要写操作在主节点上完成日志提交就行了,不用考虑replica acknowledged写关注。(journaled写关注只是一种逻辑上的写关注级别,实际并没有这个配置项值,组合w和j两个配置项才能实现用户期望的写关注。)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。