記一次Mongodb中admin數(shù)據(jù)庫(kù)導(dǎo)致的事故
前言
MongoDB副本集默認(rèn)會(huì)創(chuàng)建local、admin數(shù)據(jù)庫(kù),local數(shù)據(jù)庫(kù)主要存儲(chǔ)副本集的元數(shù)據(jù),admin數(shù)據(jù)庫(kù)則主要存儲(chǔ)MongoDB的用戶、角色等信息。
Mongodb的gridfs一次插入數(shù)據(jù)的時(shí)候會(huì)自動(dòng)創(chuàng)建幾個(gè)索引,我們程序里面的賬號(hào)沒(méi)有createIndex權(quán)限,我需要手動(dòng)創(chuàng)建一下。結(jié)果連接到mongo服務(wù)器之后忘記執(zhí)行use xxxdb來(lái)切換數(shù)據(jù)庫(kù)了,于是在admin數(shù)據(jù)庫(kù)里面創(chuàng)建了一個(gè)索引,結(jié)果導(dǎo)出一邊的程序報(bào)出來(lái)很多驗(yàn)證問(wèn)題。
Mongo的admin數(shù)據(jù)庫(kù)太脆弱了,只是創(chuàng)建一個(gè)索引就掛了。長(zhǎng)個(gè)教訓(xùn),以后千萬(wàn)不要手動(dòng)修改它,更不要用admin保存數(shù)據(jù)。
反思一下,這次操作失誤其實(shí)爆出我平時(shí)一些不好的習(xí)慣。
首先,連接mongo應(yīng)該指定目標(biāo)數(shù)據(jù)。而我之前都是連接到admin,然后用use切換到目標(biāo)數(shù)據(jù)庫(kù)。這樣難免會(huì)忘記。
$ # 錯(cuò)誤使用 $ mongo ourdomain.com/admin -u tom -p tompass $ # 正確的使用 $ mongo ourdomain.com/mydb -u tom -p tompass --authenticationDatabase admin
第二,錯(cuò)誤的在admin數(shù)據(jù)庫(kù)執(zhí)行createIndex,返回的結(jié)果明確顯示索引創(chuàng)建成功。
{ "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1, ... }
但是我忽略了,繼續(xù)在正確的數(shù)據(jù)庫(kù)創(chuàng)建索引。不然可以早一些發(fā)現(xiàn)問(wèn)題。
最后,創(chuàng)建索引應(yīng)該自動(dòng)化,比如gridfs這種對(duì)md5, filename創(chuàng)建索引的。
慎用admin數(shù)據(jù)庫(kù)
當(dāng)Mongod啟用auth選項(xiàng)時(shí),用戶需要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)帳號(hào),訪問(wèn)時(shí)根據(jù)帳號(hào)信息來(lái)鑒權(quán),而數(shù)據(jù)庫(kù)帳號(hào)信息就存儲(chǔ)在admin數(shù)據(jù)庫(kù)下。
mongo-9551:PRIMARY> use admin switched to db admin mongo-9551:PRIMARY> db.getCollectionNames() [ "system.users", "system.version" ]
- system.version存儲(chǔ)authSchema的版本信息
- system.users存儲(chǔ)了數(shù)據(jù)庫(kù)帳號(hào)信息
- 如果用戶創(chuàng)建了自定義的角色,還會(huì)有system.roles集合
用戶可以在admin數(shù)據(jù)庫(kù)下建立任意集合,存儲(chǔ)任何數(shù)據(jù),但強(qiáng)烈建議不要使用admin數(shù)據(jù)庫(kù)存儲(chǔ)應(yīng)用業(yè)務(wù)數(shù)據(jù),最好創(chuàng)建新的數(shù)據(jù)庫(kù)。
admin數(shù)據(jù)庫(kù)里的system.users、system.roles2個(gè)集合的數(shù)據(jù),MongoDB會(huì)cache在內(nèi)存里,這樣不用每次鑒權(quán)都從磁盤(pán)加載用戶角色信息。目前cache的維護(hù)代碼,只有在保證system.users、system.roles的寫(xiě)入都串行化的情況下才能正確工作,詳情參考官方issue SERVER-16092
從代碼中我們可以看出,MongoDB將將admin數(shù)據(jù)庫(kù)上的意向?qū)戞i(MODE_IX)直接升級(jí)為寫(xiě)鎖(MODE_X),也就是說(shuō)admin數(shù)據(jù)庫(kù)的寫(xiě)入操作的鎖級(jí)別只能到DB級(jí)別,不支持多個(gè)collection并發(fā)寫(xiě)入,在寫(xiě)入時(shí)也不支持并發(fā)讀取。如果用戶在admin數(shù)據(jù)庫(kù)里存儲(chǔ)業(yè)務(wù)數(shù)據(jù),則可能遭遇性能問(wèn)題。
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é)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
C#實(shí)現(xiàn)窗體中的各個(gè)控件同比自動(dòng)放縮大小
這篇文章主要介紹了C#實(shí)現(xiàn)窗體中的各個(gè)控件同比自動(dòng)放縮大小,實(shí)現(xiàn)方式主要是利用panel控件為主題,對(duì)于每個(gè)控件的大小位置和字體這幾個(gè)屬性進(jìn)行記錄,然后根據(jù)窗體改變的大小同時(shí)放縮,需要的朋友可以參考下2014-10-102021最新版windows10系統(tǒng)MongoDB數(shù)據(jù)庫(kù)安裝及配置環(huán)境
這篇文章主要介紹了2021最新版MongoDB數(shù)據(jù)庫(kù)安裝及配置環(huán)境(windows10系統(tǒng)),本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03MongoDB數(shù)據(jù)庫(kù)文檔操作方法(必看篇)
下面小編就為大家?guī)?lái)一篇MongoDB數(shù)據(jù)庫(kù)文檔操作方法(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07centos離線安裝mongodb-database-tools方法詳解
這篇文章主要介紹了centos離線安裝mongodb-database-tools方法詳解的相關(guān)資料,需要的朋友可以參考下2022-11-11Spring Boot中使用MongoDB數(shù)據(jù)庫(kù)的方法
MongoDB是一個(gè)高性能,開(kāi)源,無(wú)模式的,基于分布式文件存儲(chǔ)的文檔型數(shù)據(jù)庫(kù),由C++語(yǔ)言編寫(xiě),其名稱來(lái)源取自“humongous”,是一種開(kāi)源的文檔數(shù)據(jù)庫(kù)──NoSql數(shù)據(jù)庫(kù)的一種。這篇文章主要介紹了Spring Boot中使用MongoDB數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下2017-12-12