MongoDB中的读写锁

原文地址html


1. MongoDB 使用的锁mongodb

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


2. 锁的粒度并发

在 2.2 版本之前,mongod 只有全局锁(锁定一个server);
从2.2 版本开始,大部分读写操做只锁一个库(database),相对以前版本,这个粒度已经降低,例如若是一个 mongod 实例上有 5 个库,若是只对一个库中的一个集合执行写操做,那么在写操做过程当中,这个库被锁;而其它 5 个库不影响。相比 RDBMS 来讲,这个粒度已经算很大了!app

更新:MongoDB 3.4版本,写操做的锁定粒度在表中数据记录(document)级别,即便操做对象多是多条数据,每条数据在被写入时都会被锁定,防止其余进程写入;可是写操做是非事务性的,即写入多条数据,即便当前写入操做尚未完成,前面已经写入的数据也能够被其余进程修改。除非指定了$isolated,一次写入操做影响的数据没法在本次操做结束以前被其余进程修改。
$isolated也是非事务性的,即若是写入过程出错,已经完成的写入操做不会被rollback;另外,$isolated须要额外的锁,没法用于sharded方式部署的集群。
官网文档连接less

3. 如何查看锁的状态ui

db.serverStatus()
db.currentOp()
mongotop # 相似top命令,每秒刷新
mongostat
the MongoDB Monitoring Service (MMS)atom


4. 哪些操做会对数据库产生锁?spa

下表列出了常见数据库操做产生的锁。日志

操做 锁定类型
查询 读锁
经过cursor读取数据 读锁
插入数据 写锁
删除数据 写锁
修改数据 写锁
Map-reduce 读写锁均有,除非指定为non-atomic,部分mapreduce任务能够同时执行(猜想是生成的中间表不冲突的状况下)
添加index 经过前台API添加index,锁定数据库一段时间
db.eval() 写锁,同时阻塞其余运行在MongoDB上的JavaScript进程
eval 写锁,若是设定锁定选项是nolock,则不会有些锁,并且eval没法向数据库写入数据
aggregate() 读锁

 

附上原文:
Operation Lock Type
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. db.eval() blocks all other JavaScript processes.
eval Write lock. If used with the nolock lock option, the eval option does not take a write lock and cannot write data to the database.
aggregate() Read lock

 

5. 哪些数据库管理操做会锁数据库?

某些数据库管理操做会 exclusively 锁住数据库,如下命令须要申请 exclusively 锁,并锁定一段时间

db.collection.ensureIndex(),
reIndex,
compact,
db.repairDatabase(),
db.createCollection(), when creating a very large (i.e. many gigabytes) capped collection,
db.collection.validate(),
db.copyDatabase() # 可能会锁定全部数据库(database)


如下命令须要申请 exclusively 锁,但锁定很短期。

db.collection.dropIndex(),
db.collection.getLastError(),
db.isMaster(),
rs.status() (i.e. replSetGetStatus,)
db.serverStatus(),
db.auth(), and
db.addUser().

备注:可见,一些查看命令也会锁库,在比较繁忙的生产库中,也会有影响的。


6. MongoDB内部可能锁住多个库的操做

如下数据库内部操做会锁定多个库。

日志管理 MongoDB的内部操做,每一个一段时间就锁定全部数据库,全部的数据库共享一份日志
用户认证 锁定admin数据库和用户正在申请访问的数据库
全部写入备份数据库(replica)的操做都会锁定写入目标数据库和本地数据库,本地数据库的写入锁容许写入主节点的oplog

原文:Journeying, which is an internal operation, locks all databases for short intervals. All databases share a single journal.User authentication locks the admin database as well as the database the user is accessing.All writes to a replica set’s primary lock both the database receiving the writes and the local database. The lock for the local database allows the mongod to write to the primary’s oplog.

相关文章
相关标签/搜索