MongoDB副本集默認會創建local、admin數據庫,local數據庫主要存儲副本集的元數據,admin數據庫則主要存儲MongoDB的用戶、角色等信息。
慎用local數據庫
local數據庫,從名字可以看出,它只會在本地存儲數據,即local數據庫里的內容不會同步到副本集里其他節點上去;目前local數據庫主要存儲副本集的配置信息、oplog信息,這些信息是每個Mongod進程獨有的,不需要同步到副本集種其他節點。
在使用MongoDB時,重要的數據千萬不要存儲在local數據庫中
,否則當一個節點故障時,存儲在local里的數據就會丟失。
另外,對於重要的數據,除了不能存儲在local數據庫,還要注意MongoDB默認的WriteConcern是{w: 1}
,即數據寫到Primary上(不保證journal已經寫成功)就向客戶端確認,這時同樣存在丟數據的風險。對於重要的數據,可以設置更高級別的如{w: "majority"}
來保證數據寫到大多數節點后再向客戶端確認,當然這對寫入的性能會造成一定的影響。
慎用admin數據庫
當Mongod啟用auth選項時,用戶需要創建數據庫帳號,訪問時根據帳號信息來鑒權,而數據庫帳號信息就存儲在admin數據庫下。
mongo-9551:PRIMARY> use admin
switched to db admin
mongo-9551:PRIMARY> db.getCollectionNames()
[ "system.users", "system.version" ]
- system.version存儲authSchema的版本信息
- system.users存儲了數據庫帳號信息
- 如果用戶創建了自定義的角色,還會有system.roles集合
用戶可以在admin數據庫下建立任意集合,存儲任何數據,但強烈建議不要使用admin數據庫存儲應用業務數據
,最好創建新的數據庫。
admin數據庫里的system.users、system.roles2個集合的數據,MongoDB會cache在內存里,這樣不用每次鑒權都從磁盤加載用戶角色信息。目前cache的維護代碼,只有在保證system.users、system.roles的寫入都串行化的情況下才能正確工作,詳情參考官方issue SERVER-16092
從代碼中我們可以看出,MongoDB將將admin數據庫上的意向寫鎖(MODE_IX)
直接升級為寫鎖(MODE_X)
,也就是說admin數據庫的寫入操作的鎖級別只能到DB級別
,不支持多個collection並發寫入,在寫入時也不支持並發讀取。如果用戶在admin數據庫里存儲業務數據,則可能遭遇性能問題。