1. MongoDB 使用的鎖mongodb
MongoDB 使用的是「readers-writer」鎖, 能夠支持併發但有很大的侷限性
當一個讀鎖存在,許多讀操做可使用這把鎖,然而, 當一個寫鎖的存在,一個單一的寫操做會」exclusively「持有該鎖,同一時間其它寫操做不能使用共享這個鎖;
舉個例子,假設一個集合裏有10個文檔,多個update操做不能併發在這個集合上,即便是更新不一樣的文檔。數據庫
2. 鎖的粒度併發
在 2.2 版本之前,一個mongodb實例一個寫鎖,多個讀鎖。也就是說mongod 只有全局鎖(鎖定一個server);app
在2.2-3.0的版本,一個數據庫一個寫鎖,多個讀鎖。例如若是一個 mongod 實例上有 5 個庫,若是隻對一個庫中的一個集合執行寫操做,那麼在寫操做過程當中,這個庫被鎖;而其它 4 個庫不影響。相比 RDBMS 來講,這個粒度已經算很大了!less
在3.0以後的版本,WiredTiger提供了文檔(不是集合)級別的鎖。ui
更新:MongoDB 3.4版本,寫操做的鎖定粒度在表中數據記錄(document)級別,即便操做對象多是多條數據,每條數據在被寫入時都會被鎖定,防止其餘進程寫入;可是寫操做是非事務性的,即寫入多條數據,即便當前寫入操做尚未完成,前面已經寫入的數據也能夠被其餘進程修改。除非指定了$isolated,一次寫入操做影響的數據沒法在本次操做結束以前被其餘進程修改。
$isolated也是非事務性的,即若是寫入過程出錯,已經完成的寫入操做不會被rollback;另外,$isolated須要額外的鎖,沒法用於sharded方式部署的集羣。
官網文檔連接atom
MongoDB高吞吐的緣由:spa
3. 如何查看鎖的狀態日誌
db.serverStatus()
db.currentOp()
mongotop # 相似top命令,每秒刷新
mongostat
the MongoDB Monitoring Service (MMS)server
4. 哪些操做會對數據庫產生鎖?
下表列出了常見數據庫操做產生的鎖。
操做 | 鎖定類型 |
查詢 | 讀鎖 |
經過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.