記一次Mongodb中admin數(shù)據(jù)庫導致的事故
前言
MongoDB副本集默認會創(chuàng)建local、admin數(shù)據(jù)庫,local數(shù)據(jù)庫主要存儲副本集的元數(shù)據(jù),admin數(shù)據(jù)庫則主要存儲MongoDB的用戶、角色等信息。
Mongodb的gridfs一次插入數(shù)據(jù)的時候會自動創(chuàng)建幾個索引,我們程序里面的賬號沒有createIndex權(quán)限,我需要手動創(chuàng)建一下。結(jié)果連接到mongo服務器之后忘記執(zhí)行use xxxdb來切換數(shù)據(jù)庫了,于是在admin數(shù)據(jù)庫里面創(chuàng)建了一個索引,結(jié)果導出一邊的程序報出來很多驗證問題。
Mongo的admin數(shù)據(jù)庫太脆弱了,只是創(chuàng)建一個索引就掛了。長個教訓,以后千萬不要手動修改它,更不要用admin保存數(shù)據(jù)。
反思一下,這次操作失誤其實爆出我平時一些不好的習慣。
首先,連接mongo應該指定目標數(shù)據(jù)。而我之前都是連接到admin,然后用use切換到目標數(shù)據(jù)庫。這樣難免會忘記。
$ # 錯誤使用 $ mongo ourdomain.com/admin -u tom -p tompass $ # 正確的使用 $ mongo ourdomain.com/mydb -u tom -p tompass --authenticationDatabase admin
第二,錯誤的在admin數(shù)據(jù)庫執(zhí)行createIndex,返回的結(jié)果明確顯示索引創(chuàng)建成功。
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1,
...
}
但是我忽略了,繼續(xù)在正確的數(shù)據(jù)庫創(chuàng)建索引。不然可以早一些發(fā)現(xiàn)問題。
最后,創(chuàng)建索引應該自動化,比如gridfs這種對md5, filename創(chuàng)建索引的。
慎用admin數(shù)據(jù)庫
當Mongod啟用auth選項時,用戶需要創(chuàng)建數(shù)據(jù)庫帳號,訪問時根據(jù)帳號信息來鑒權(quán),而數(shù)據(jù)庫帳號信息就存儲在admin數(shù)據(jù)庫下。
mongo-9551:PRIMARY> use admin switched to db admin mongo-9551:PRIMARY> db.getCollectionNames() [ "system.users", "system.version" ]
- system.version存儲authSchema的版本信息
- system.users存儲了數(shù)據(jù)庫帳號信息
- 如果用戶創(chuàng)建了自定義的角色,還會有system.roles集合
用戶可以在admin數(shù)據(jù)庫下建立任意集合,存儲任何數(shù)據(jù),但強烈建議不要使用admin數(shù)據(jù)庫存儲應用業(yè)務數(shù)據(jù),最好創(chuàng)建新的數(shù)據(jù)庫。
admin數(shù)據(jù)庫里的system.users、system.roles2個集合的數(shù)據(jù),MongoDB會cache在內(nèi)存里,這樣不用每次鑒權(quán)都從磁盤加載用戶角色信息。目前cache的維護代碼,只有在保證system.users、system.roles的寫入都串行化的情況下才能正確工作,詳情參考官方issue SERVER-16092
從代碼中我們可以看出,MongoDB將將admin數(shù)據(jù)庫上的意向?qū)戞i(MODE_IX)直接升級為寫鎖(MODE_X),也就是說admin數(shù)據(jù)庫的寫入操作的鎖級別只能到DB級別,不支持多個collection并發(fā)寫入,在寫入時也不支持并發(fā)讀取。如果用戶在admin數(shù)據(jù)庫里存儲業(yè)務數(shù)據(jù),則可能遭遇性能問題。
if (supportsDocLocking() || enableCollectionLocking) {
if (supportsDocLocking() || enableCollectionLocking) {
+
+ // The check for the admin db is to ensure direct writes to auth collections
+ // are serialized (see SERVER-16092).
+ if (_id == resourceIdAdminDB && !isRead) {
+ _mode = MODE_X;
+ }
+
_lockState->lock(_id, _mode);
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
Windows系統(tǒng)下安裝MongoDB并內(nèi)網(wǎng)穿透遠程連接
這篇文章主要給大家介紹了關(guān)于Windows系統(tǒng)下安裝MongoDB并內(nèi)網(wǎng)穿透遠程連接的相關(guān)資料,文中通過圖文將步驟介紹的非常詳細,對大家學習或者使用MongoDB具有一定的參考學習價值,需要的朋友可以參考下2023-03-03
MongoDB模糊查詢正則regex(類似like?和?not?like)
在類關(guān)系型數(shù)據(jù)庫中,like和not?like是常用的模糊查詢操作符,它允許我們在匹配字段的時候使用通配符,在MongoDB中,也有類似的操作符,MongoDB?可以使用?$regex?操作符來設置匹配字符串的正則表達式,MongoDB?使用?PCRE(Perl?兼容的正則表達式)作為正則表達式語言2024-02-02
Windows系統(tǒng)啟動MongoDB報錯無法連接服務器的問題及解決方案
在Windows系統(tǒng)中啟動MongoDB時遇到連接拒絕的錯誤,通常是因為服務未運行或配置問題,本文給大家分享Windows系統(tǒng)啟動MongoDB報錯無法連接服務器的問題及解決方案,一起看看吧2024-10-10
MongoDB系列教程(六):java操作mongodb實例
這篇文章主要介紹了MongoDB系列教程(六):java操作mongodb實例,本文講解了java中操作mongodb數(shù)據(jù)增加、刪除、修改、查詢數(shù)據(jù)等代碼實例,需要的朋友可以參考下2015-05-05

