一、单个MongoDB实例
1、MongoDB使用的是多读单写锁(reads-write lock),读锁可以共享,写锁只能有一个写操作,并且写锁的优先级高于读锁。
2、MongoDB锁大多数是基于数据库级别的(从2.2版本开始)
3、MongoDB锁会锁住多个数据库的操作:
db.copyDatabase()会锁住整个MongoDB实例
Journaling 内部操作,会锁住所有数据库非常短的时间,所有数据库共享一个journal
User authentication会锁住admin数据库和用户需要访问的数据库
所有写入复制集的primary的操作都会同时锁住需要写入数据的数据库和local数据库,local数据库的锁允许向primary的oplog集合写入数据
4、释放锁的机制
在一些情况下,读和写操作会释放他们的锁。
1)在影响多个文档的写操作过程中(如多文档修改),会定期释放写锁操作来允许其他读操作进行。类似的,长时间运行的读锁过程中,会定期释放读锁使写操作能够有机会去完成。
2)在执行读操作之前,MongoDB会监测内存,预测数据是否存在在内存里,如果MongoDB监测到数据不存在,读操作会在MongoDB从磁盘数据文件加载数据到内存过程中释放锁,当数据全部加载完成,它会重新去获取锁完成操作。
如遇到page fault,需要去数据库加载数据的情况下,MongoDB就会再加载数据的过程中先释放锁来解约资源。
5、查看锁的状态的命令
db.serverStatus()
db.currentOp()
Mongotop
mongoStat
ServerStatus返回的关于锁的文档,或者currentOp方法返回的关于锁的字段提供了MongoDB中锁的类型和争夺锁队列的数量。
二、复制集中的锁
1、所有写入复制集的primary的操作都会同时锁住需要写入数据的数据库和local数据库,local数据库的锁允许向primary的oplog集合写入数据。
上面这条规则使复制集的写速度并没有提高,所有数据集的写操作都会伴有oplog的写操作,这会导致其他的写操作同样会被阻塞。不过还是提高了读数据的性能。
2、在secondary从primary同步数据,对secondary中的oplog和数据进行写数据时,secondary也不能进行读操作。
三、sharding中的锁
Sharding是有许多个MongoDB实例组成,每个MongoDB实例有自己的整套锁机制。所以sharding是通过分流来提高整体锁的性能,对于单个的锁的机制,是没有变化的。
四、官网的锁的介绍