mongodb的并发与锁
背景
mongodb操作数据库可以分为两种类型,读和写。大概可以分为3个级别数据库层面,集合层面,文档层面,这篇文章主要解释当mongodb并发发生这些操作时,mongodb如何控制
- mongodb 的读写锁
- mongodb 读写锁的多粒度控制
- mongodb 意向锁(intent lock)
mongodb的读写锁
- 读取mongodb的数据使用的锁是共享锁(shared(S) locking),简单的说就是可以多个客户端同时读取一个固定资源的数据,比如以下几种读可以完全并发发生
show dbs
show collections
db.student.find({name:1})
- 更新mongodb数据的时候使用的是排它锁(exclution(X) locking),一个更新发生的时候会启用这个锁,然后导致其它更新不能发生。
读写锁的多粒度控制
上一个章节粗略的介绍了读写锁的概念,那我们会有以下几个问题
- 更新数据库A名字的时候是不是不能更新数据库B的名字
- 更新集合A名字的时候是不是不能更新集合B的名字
- 更新集合student里面文档{name:‘张三’,age:19}的时候是不是不能更新{name:‘张三’,age:19} 对于上面这些问题,答案是否定的,因为mongodb有全局锁,数据库锁,集合锁,和文档锁等不同粒度的锁,能够控制锁在不同粒度排它,比如更新一个集合A,同时完全可以更新一个集合B,也完全可以对数据库进行更新操作,但是不能操作集合A下面的数据。 同时mongodb最小粒度的锁是文档级别,可以同时更新一个集合里面的不同文档
在mongodb的3.0及以前,默认使用MMAPv1引擎,锁的最小粒度是在集合层面,在3.2mongodb的默认引擎使用了WiredTiger之后,锁的粒度在文档层面
意向锁(intent lock)
意向锁主要的目的是向下控制,如果一个集合student发生更新,那么就会产生一个意向排他锁(intent exclution lock),就不用使用文档级别的读写锁,照样不能更新student文档,不能读取student文档,直到这个锁被释放