What type of locking does MongoDB use?
mongodb用的是什么类型的锁
MongoDB uses a readers-writer [1] lock that allows concurrent reads access to a database but gives exclusive access to a single write operation.
mongodb使用读写锁(共享-排他锁、多读单写锁),允许对数据库进行并发的读访问,并且对每一个写操作提供排他的访问。
When a read lock exists, many read operations may use this lock. However, when a write lock exists, a single write operation holds the lock exclusively, and no other read or write operations may share the lock.
当存在一个读锁时,很多读操作均可使用这个锁。当一个写锁出现,一个写操作排他的占有该锁,并且不被其他的读或者写操作共享。
Locks are “writer greedy,” which means writes have preference over reads. When both a read and write are waiting for a lock, MongoDB grants the lock to the write.
锁是偏向于写操作的,即相对于读操作,写操作有更高的优先权。当一个读和写操作同时在等待一个锁时,mongodb优先给写操作分配锁。
How granular are locks in MongoDB?
Changed in version 2.2.
mongodb中锁的粒度
Beginning with version 2.2, MongoDB implements locks on a per-database basis for most read and write operations. Some global operations, typically short lived operations involving multiple databases, still require a global “instance” wide lock. Before 2.2, there is only one “global” lock per mongod instance.
从2.2版本起,对大多数读写操作,mongodb实现了基于数据库的锁。全局操作,典型的比如涉及多个数据库的short lived操作,依旧会请求实例级别的全局锁,在2.2之前,每个mongodb实例只有一个全局锁。
For example, if you have six databases and one takes a write lock, the other five are still available for read and write.
例如,如果你有六个数据库,其中一个有写锁,其他的五个仍然可以进行读写。
How do I see the status of locks on my mongod instances?
我如何查看mongod实例的锁状态
For reporting on lock utilization information on locks, use any of the following methods:
db.serverStatus(),
db.currentOp(),
mongotop,
mongostat, and/or
the MongoDB Monitoring Service (MMS)
Specifically, the locks document in the output of serverStatus, or the locks field in the current operation reporting provides insight into the type of locks and amount of lock contention in your mongod instance.
To terminate an operation, use db.killOp().
Does a read or write operation ever yield the lock?
New in version 2.0.
读写操作会交出锁吗?
A read and write operations will yield their locks if the mongod receives a page fault or fetches data that is unlikely to be in memory. Yielding allows other operations that only need to access documents that are already in memory to complete while mongod loads documents into memory.
如果mongod接收到未命中的缓存页或者去取不在内存中的数据,读写操作将放弃他们的锁。这样就允许mongod进行其他只需要访问内存里的文档即可完成的操作,同时加载自身需要的数据到内存。
Additionally, write operations that affect multiple documents (i.e. update() with the multi parameter,) will yield periodically to allow read operations during these log write operations. Similarly, long running read locks will yield periodically to ensure that write operations have the opportunity to complete.
此外,多个文档上的写操作(比如带有multi操作的update),在日志写的时间内,会周期性地交出锁以容许读操作。类似的,长时间的读锁也会定期的退让以便写操作有机会完成。
Changed in version 2.2: The use of yielding expanded greatly in MongoDB 2.2. Including the “yield for page fault.” MongoDB tracks the contents of memory and predicts whether data is available before performing a read. If MongoDB predicts that the data is not in memory a read operation yields its lock while MongoDB loads the data to memory. Once data is available in memory, the read will reacquire the lock to completes the operation.
2.2版本极大地扩展了yielding,包括因为page fault的yielding。mongodb会跟踪内存并在执行一个读之前预判数据是否可用。如果数据不在内存,读操作即交出锁同时mongodb加载数据到内存。一旦数据到了内存,该读操作会再次搜索那个读锁完成此次操作。
##################################################
--1 MongoDB 使用的锁
MongoDB 使用的是“readers-writer”锁, 可以支持并发但有很大的局限性,当一个读锁存在,许多
读操作可以使用这把锁,然而, 当一个写锁的存在,一个单一的写操作会 exclusively 持有该锁,同时
其它读,写操作不能使用共享这个锁;举个例子,假设一个集合里有 10 个文档,多个 update 操作不能
并发在这个集合上,即使是更新不同的文档。
--2 锁的粒度
在 2.2 版本以前,mongod 只有全局锁;在 2.2 版本开始,大部分读写操作只锁一个库,相对之前版本,
这个粒度已经下降,例如如果一个 mongod 实例上有 5 个库,如果只对一个库中的一个集合执行写操作,那
么在写操作过程中,这个库被锁;而其它 5 个库不影响。相比 RDBMS 来说,这个粒度已经算很大了!
--3 如何查看锁的状态
db.serverStatus()
db.currentOp()
mongotop
mongostat
the MongoDB Monitoring Service (MMS)
--4 哪些操作会对数据库产生锁?
下表列出了常见数据库操作产生的锁。
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().This operation may lock all databases
以下命令需要申请 exclusively 锁,但锁定很短时间。
db.collection.dropIndex(),
db.collection.getLastError(),
db.isMaster(),
rs.status() (i.e. replSetGetStatus,)
db.serverStatus(),
db.auth(), and
db.addUser().
备注:可见,一些查看命令也会锁库,在比较繁忙的生产库中,也会有影响的。
--6 锁住多个库的操作
以下数据库操作会锁定多个库。
db.copyDatabase() must lock the entire mongod instance at once.
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.