Mongodb GetLastError写入安全机制

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 一、简介很多人抱怨mongodb是内存数据库,也没有事务,会不安全,其实这都是对Mongodb的误解,Mongodb有完整的redolog,binlog和持久化机制,不必太担心数据丢失问题。

一、简介

很多人抱怨mongodb是内存数据库,也没有事务,会不安全,其实这都是对Mongodb的误解,Mongodb有完整的redolog,binlog和持久化机制,不必太担心数据丢失问题。

journal是Mongodb中的redo log,而Oplog则是负责复制的binlog(对应Mysql)。

在google.groupuser上,mongo的开发者有一段这样的解释:

#########
By default:
Collection data (including oplog) is fsynced to disk every 60 seconds.
Write operations are fsynced to journal file every 100 milliseconds.
Note, oplog is available right away in memory for slaves to read. Oplog is a capped collection
so a new oplog is never created, old data just rolls off.
GetLastError with params:
(no params) = return after data updated in memory.
fsync: true:
with --journal = wait for next fsync to journal file (up to 100 milliseconds);
without --journal = force fsync of collection data to disk then return.
w: 2 = wait for data to be updated in memory on at least two replicas.
########

可以看到:

1、如果打开journal,那么即使断电也只会丢失100ms的数据,这对大多数应用来说都可以容忍了。从1.9.2+,mongodb都会默认打开journal功能,以确保数据安全。而且journal的刷新时间是可以改变的,2-300ms的范围,使用 --journalCommitInterval 命令。

2、Oplog和数据刷新到磁盘的时间是60s,对于复制来说,不用等到oplog刷新磁盘,在内存中就可以直接复制到Sencondary节点。

GetLastError Command

getLastError 是Mongodb的一个命令,从名字上看,它好像是取得最后一个error,但其实它是Mongodb的一种客户端阻塞方式。用这个命令来获得写操作是否成功的信息。

getlastError有几个参数:j,w,fsync。在大多数的语言驱动中,这个命令是被包装成writeConcern类,比如java。

二、什么时候使用这个命令:

1、Mongodb的写操作默认是没有任何返回值的,这减少了写操作的等待时间,也就是说,不管有没有写入到磁盘或者有没有遇到错误,它都不会报错。但一般我们是不放心这么做的,这时候就调用getlastError命令,得到返回值。

以java为例,举个例子:当我们为字段建立了一个唯一索引,针对这个字段我们插入两条相同的数据,不设置WriterConcern或者设置WriterConcern.NORMAL模式,这时候即便抛出异常,也不会得到任何错误。insert()函数在java中的返回值是WriteResult类,

这个类实际上包装了getlastError的返回值,但是这时候WriteResult的_lastErrorResult属性实际上是空的。因为dup key错误是server error,只有在WriterConcern.SAFE或更高级别的模式下,才会得到server error。

2、在多线程模式下读写Mongodb的时候,如果这些读写操作是有逻辑顺序的,那么这时候也有必要调用getlasterror命令,用以确保上个操作执行完下个操作才能执行,因为两次执行的连接有可能是不同的。在大多数情况下,我们都会使用连接池去连接mongodb,所以这是需要注意的。

举个例子:我们之前遇到这个异常"The connection may have been used since this write, cannot obtain a result",异常原因有两个,连接池数量太小,竞争太激烈,没有设置writerConcern.SAFE。
参见:https://groups.google.com/forum/?fromgroups=#!topic/mongodb-user/xzw0Cb831VY
PS:在java等语言中,是不需要显示调用这个命令的,只需要设置WriterConcern即可。

三、getlastError最佳实践

1、如果没有特殊要求,最低级别也要使用WriterConcern.SAFE,即w=1。

2、对于不重要的数据,比如log日志,可以使用WriterConcern.NONE或者WriterConcern.NORMAL,即w=-1或者w=0,省去等待网络的时间。

3、对大量的不连续的数据写入,如果每次写入都调用getLastError会降低性能,因为等待网络的时间太长,这种情况下,可以每过N次调用一下getLastError。但是在Shard结构上,这种方式不一定确保之前的写入是成功的。

4、对连续的批量写入(batchs of write),要在批量写入结束的时候调用getlastError,这不仅能确保最后一次写入正确,而且也能确保所有的写入都能到达服务器。如果连续写入上万条记录而不调用getlastError,那么不能确保在同一个TCP socket里所有的写入都成功。这在并发的情况下可能就会有问题。避免这个并发问题,可以参考如何在一个链接(请求)里完成批量操作,URL:java driver concurrency
http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency

5、对数据安全要求非常高的的配置:j=true,w="majority" db.runCommand({getlasterror:1,j:true,w:'majority',wtimeout:10000})
java语言可以在MongoOption中设置,MongoOption中的这些设置是全局的,对于单独的一个(连接)操作,还可以分别设置。

参考:
1、http://www.mongodb.org/display/DOCS/Journaling
2、http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency
3、http://www.mongodb.org/display/DOCS/getLastError+Command
转自:http://blog.chinaunix.net/uid-15795819-id-3373361.html

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
11月前
|
安全 NoSQL MongoDB
20 MongoDB高级 - 用户管理安全
20 MongoDB高级 - 用户管理安全
69 1
|
JSON NoSQL MongoDB
mongodb基本操作,增删改查,查询,索引,权限机制
mongodb基本操作,增删改查,查询,索引,权限机制
|
2月前
|
NoSQL 安全 MongoDB
【MongoDB深度揭秘】你的更新操作真的安全了吗?MongoDB fsync机制大起底,数据持久化不再是谜!
【8月更文挑战第24天】MongoDB是一款备受欢迎的NoSQL数据库,以其灵活的文档模型和强大的查询能力著称。处理关键业务数据时,数据持久化至关重要。本文深入探讨MongoDB的写入机制,特别是更新操作时的fsync行为。MongoDB先将数据更新至内存以提升性能,而非直接写入磁盘。fsync的作用是确保数据从内存同步到磁盘,但MongoDB并非每次更新后都立即执行fsync。通过设置不同的写入关注级别(如w:0、w:1和w:majority),可以平衡数据持久性和性能。
40 1
|
2月前
|
持续交付 C# 敏捷开发
“敏捷之道:揭秘WPF项目中的快速迭代与持续交付——从需求管理到自动化测试,打造高效开发流程的全方位指南”
【8月更文挑战第31天】敏捷开发是一种注重快速迭代和持续交付的软件开发方法,通过短周期开发提高产品质量并快速响应变化。本文通过问题解答形式,探讨在Windows Presentation Foundation(WPF)项目中应用敏捷开发的最佳实践,涵盖需求管理、版本控制、自动化测试及持续集成等方面,并通过具体示例代码展示其实施过程,帮助团队提升代码质量和开发效率。
63 0
|
5月前
|
NoSQL MongoDB 数据库
【MongoDB 专栏】MongoDB 的并发控制与锁机制
【5月更文挑战第11天】MongoDB的并发控制和锁机制保证数据一致性和性能。全局锁用于特殊情况如数据库初始化,限制并发性能;文档级锁提供更高的并发性,针对单个文档锁定。乐观并发控制利用版本号检查减少锁竞争。在分布式环境下,需协调多节点锁,优化包括合理设计数据模型、调整锁配置和利用分布式事务。未来,MongoDB将持续改进这些机制以应对复杂需求。了解并发控制原理对于数据库开发者至关重要。
230 2
【MongoDB 专栏】MongoDB 的并发控制与锁机制
|
3月前
|
存储 NoSQL 关系型数据库
MongoDB的配置服务器和复制机制
【7月更文挑战第2天】MongoDB配置服务器存储分片和权限元数据,支持在主节点故障时保持读服务。关键组件,性能影响显著。复制集包含Primary和Secondary,通过oplog实现数据同步,类似MySQL binlog。oplog的幂等性可能导致大量set操作,且大小受限,可能导致从节点需全量同步。读写分离提升效率,主从切换确保高可用。
40 0
|
3月前
|
负载均衡 NoSQL 中间件
|
5月前
|
存储 NoSQL 大数据
【MongoDB】GridFS机制
【4月更文挑战第2天】【MongoDB】GridFS机制
|
5月前
|
NoSQL 安全 MongoDB
MongoDB安全机制:认证、授权与加密
【4月更文挑战第30天】MongoDB提供全面的安全机制,包括认证(用户名/密码、LDAP、Kerberos、x.509证书)、授权(基于角色的访问控制,RBAC)和加密(TLS/SSL、透明数据加密TDE、字段级加密FLE),确保数据保密性、完整性和可用性。通过合理配置这些机制,企业可保障数据安全,应对不断变化的安全威胁。
|
5月前
|
监控 NoSQL MongoDB
MongoDB索引机制与优化策略详解
【4月更文挑战第30天】本文深入解析MongoDB的索引机制,包括单字段、复合、地理空间、全文及哈希索引。介绍了创建与查看索引的方法,并提出了优化策略:选择性创建、使用复合索引、定期审查优化、避免不必要的索引扫描、利用索引前缀与覆盖索引,以及监控索引使用。通过这些策略,可提升MongoDB查询性能。