MongoDB磁盤空間占滿導致數(shù)據(jù)庫被鎖定的解決方法
一、問題
1、我在實際項目中,遇到一個問題,隨著數(shù)據(jù)每天的不斷增加,導致mongodb的磁盤空間站滿了,數(shù)據(jù)庫被鎖了,無法使用。
2、故障表現(xiàn)
- 部署的應用程序突然無法將數(shù)據(jù)寫入數(shù)據(jù)庫,但是可以正常讀取數(shù)據(jù)。
- 管理人員通過客戶端連接數(shù)據(jù)庫進行排查時,可以寫入一條數(shù)據(jù),返回錯誤信息:
not authorized on xxxx to execute command
3、檢查磁盤空間是否被耗盡
登錄mongodb管理控制臺,查看實例的狀態(tài),會發(fā)現(xiàn)已被鎖定,并且磁盤空間占用已經100%
優(yōu)化之前數(shù)據(jù)和磁盤情況:
二、解決方案
1、兩種方案:
(1)通過變更配置方案,擴充磁盤空間,來提升實例的磁盤空間
(2)刪除數(shù)據(jù)庫中的數(shù)據(jù),回收磁盤碎片以提升磁盤利用率,來減少數(shù)據(jù)存儲空間,降低磁盤占用空間
我選擇了第二種方案,因為我的數(shù)據(jù)庫中,有很多非必要的數(shù)據(jù)可以刪除,可以騰出不少磁盤空間。
2、注意問題
這里一定要注意,并不是在MongoDB實例數(shù)據(jù)庫中刪除數(shù)據(jù),就能夠釋放MongoDB實例的磁盤空間。在刪除云數(shù)據(jù)庫MongoDB實例的數(shù)據(jù)后,這些被刪除數(shù)據(jù)使用的存儲空間會被標記為空閑,隨后寫入的新數(shù)據(jù)可能會被直接存儲到這部分空閑的存儲空間中,也可能會先擴展文件的存儲空間再存儲到文件末尾。上述情況將導致一部分空閑的存儲空間不會被使用,這些未被使用的空閑存儲空間被稱之為磁盤碎片,磁盤碎片越多,磁盤利用率就越低。
3、背景信息
(1)執(zhí)行db.runCommand({collStats: <collection_name>})
命令訪問節(jié)點時,返回結果有兩個關鍵字:size
和storageSize
。其中,size
表示集合的邏輯存儲大小,storageSize
表示集合的物理存儲大小。在執(zhí)行remove
命令刪除文檔后,size
的值會減少,但是,storageSize
的值不一定會減少。當storageSize
大于size
時,表示已產生磁盤碎片。
(2)compact
是云數(shù)據(jù)庫MongoDB的壓縮命令,執(zhí)行compact
命令可以回收刪除數(shù)據(jù)后產生的磁盤碎片,實現(xiàn)壓縮磁盤空間的目的,從而提升磁盤利用率。
4、刪除數(shù)據(jù)庫數(shù)據(jù)
這里以表valueOpenData為例子,針對主節(jié)點,進行演示操作,之前已經清理了一部分表的磁盤空間,現(xiàn)已經不是100%。
刪除數(shù)據(jù),是不會減少磁盤空間的,這個一定要注意。
執(zhí)行刪除方案,刪除某一段時間之前的數(shù)據(jù):
db.valveOpenData.deleteMany({ "dataReadTime": { "$lte": ISODate("2022-12-30T23:59:59Z") } })
5、查看集合需回收的磁盤碎片空間
刪除數(shù)據(jù) 清理磁盤之前的總磁盤占用情況
刪除數(shù)據(jù)清理磁盤之前的磁盤占用空間
刪除數(shù)據(jù)清理磁盤之前的數(shù)據(jù)庫情況
執(zhí)行查看集合需回收的磁盤碎片空間語句
db.valveOpenData.stats().wiredTiger["block-manager"]["file bytes available for reuse"]
結果:可清理磁盤碎片 9161187328 byte
6、回收單節(jié)點或副本集實例的磁盤碎片
單節(jié)點實例只有一個StandAlone節(jié)點,您只需要連接主節(jié)點(Primary節(jié)點),執(zhí)行compact命令回收主節(jié)點(Primary節(jié)點)的磁盤碎片。
副本集實例具有多個節(jié)點,您需要分別連接主節(jié)點(Primary節(jié)點)和從節(jié)點(Secondary節(jié)點),在不同節(jié)點上執(zhí)行compact命令回收相應節(jié)點的磁盤碎片,執(zhí)行的回收命令相同。
我這里回收的是主節(jié)點(Primary節(jié)點)磁盤碎片。
執(zhí)行語句
db.runCommand({compact:"valveOpenData"})
強制執(zhí)行語句
db.runCommand({compact:"valveOpenData",force:true})
執(zhí)行成功的返回結果如下:{ "ok" : 1 } ,清理磁盤空間完成,你也可以多執(zhí)行幾次清理。
執(zhí)行查看集合需回收的磁盤碎片空間語句
db.valveOpenData.stats().wiredTiger["block-manager"]["file bytes available for reuse"]
結果:清理過后磁盤碎片 1072041984 byte
刪除數(shù)據(jù)清理磁盤之后的總磁盤占用情況
刪除數(shù)據(jù)清理磁盤之后的磁盤占用空間
刪除數(shù)據(jù)清理磁盤之后的數(shù)據(jù)庫情況
最終結果:一個表刪除數(shù)據(jù)、清理磁盤,清理出來差不多10G的磁盤空間
三、總結
對于不重要的數(shù)據(jù),為了防止數(shù)據(jù)量過大,占滿磁盤空間,需要定時清理過期或者不需要的數(shù)據(jù)。
最好寫個定時器定時刪除數(shù)據(jù)比較合適,但是要記得執(zhí)行回收磁盤碎片空間,只有執(zhí)行了回收后,才是真正回收了磁盤空間。
以上就是MongoDB磁盤空間占滿導致數(shù)據(jù)庫被鎖定的解決方法的詳細內容,更多關于MongoDB磁盤空間占滿的資料請關注腳本之家其它相關文章!
相關文章
使用aggregate在MongoDB中查詢重復數(shù)據(jù)記錄的方法
這篇文章主要介紹了使用aggregate在MongoDB中查詢重復數(shù)據(jù)記錄的方法的相關資料,需要的朋友可以參考下2016-01-01MongoDb的"not master and slaveok=false"錯誤及解決方法
今天小編就為大家分享一篇關于MongoDb的"not master and slaveok=false"錯誤及解決方法,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10