码迷,mamicode.com
首页 > 数据库 > 详细

Mongodb锁问题

时间:2017-11-21 10:51:22      阅读:423      评论:0      收藏:0      [点我收藏+]

标签:共享   需要   rom   ext   cursor   包括   完整性   操作   issue   

一.数据库级锁

MongoDB的锁机制和一般关系数据库如 MySQL(InnoDB), Oracle 有很大的差异,InnoDB 和 Oracle 能提供行级粒度锁,而 MongoDB 2.x 只能提供 库级粒度锁,这意味着当 MongoDB 一个写锁处于占用状态时,其它的读写操作都得干等。

MongoDB 使用的是“readers-writer”锁, 可以支持并发但有很大的局限性,当一个读锁存在,许多读操作可以使用这把锁,然而, 当一个写锁的存在,一个单一的写操作会 exclusively 持有该锁,同时其它读,写操作不能使用共享这个锁;举个例子,假设一个集合里有 10 个文档,多个 update 操作不能并发在这个集合上,即使是更新不同的文档。


初看起来库级锁在大并发环境下有严重的问题,但是 MongoDB 依然能够保持大并发量和高性能,这是因为 MongoDB 的锁粒度虽然很粗放,但是在锁处理机制和关系数据库锁有很大差异,主要表现在:

MongoDB 没有完整事务支持,操作原子性只到单个 document 级别,所以通常操作粒度比较小;
MongoDB 锁实际占用时间是内存数据计算和变更时间,通常很快;
MongoDB 锁有一种临时放弃机制,当出现需要等待慢速 IO 读写数据时,可以先临时放弃,等 IO 完成之后再重新获取锁


在MongoDB 3.0版本中锁的粒度就变得更细了,除了全局锁、数据库锁还加入了集合锁,而且对于WiredTiger存储引擎和MMAPv1存储引擎而言两者之间的锁机制也有不同。
 WiredTiger:对于大部分的读写操作,WiredTiger使用乐观锁。WiredTiger对于全局、数据库、集合级别只会使用意向锁。当存储引擎检测到两个操作之间的冲突,一个写冲突导致MongoDB透明地重试写操作。一些全局操作,跟2.2版本一样还是会需要全局锁,例如,删除一个集合,那么仍然还是需要一个互斥的数据库锁的。


如何查看锁的状态

db.serverStatus()
db.currentOp()
mongotop
mongostat

产生数据库锁的操作

操作 锁类型
Issue a query Read lock
Get more data from a cursor Read lock
Insert data Write lock
Remove data Write lock
Update data Write lock
Map-reduce Read lock and write lock, unless operations are specified as non-atomic. Portions of map-reduce jobs can run concurrently.
Create an index Building an index in the foreground, which is the default, locks the database for extended periods of time.

db.eval() Write lock.

二.原子操作但不支持事务

所谓原子操作就是要么对这个文档操作全部成功,要么全部失败,不会出现查询到的文档没有保存完整的情况
mongodb不支持事务,所以,在你的项目中应用时,要注意这点。无论什么设计,都不要要求mongodb保证数据的完整性。但是mongodb对单个文档的操作提供了许多原子操作,比如文档的保存,修改(包括对单个文档修改多个字段),删除等,都是原子操作。

 

Mongodb锁问题

标签:共享   需要   rom   ext   cursor   包括   完整性   操作   issue   

原文地址:http://www.cnblogs.com/l1pe1/p/7871790.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!