MongoDB 備份 導出導入數據的方法和注意事項

MongoDB  備份 導出導入數據的方法和注意事項


週二有同學問,MONGODB怎麼備份,怎麼數據遷移,正好最近要做一個項目的數據遷移,其中就有MONGODB ,正好以一個項目的觀念來看看MongoDb的數據遷移和備份的觀點,如果有遺漏或三觀不正,還是請大家來指正。


做這個事情,其實要先有一個測試環節,或者生產環境,這裡就以兩個單機的MOGNODB4.0 來進行操作。本身MONGODB 是支持兩種數據的遷出和導入的方式,當然後面也會有兩個複製集合之間的數據遷移的東西。

一般小型系統使用mongodump 和 mongorestore 來進行系統的備份和恢復mongodump可以用來轉儲整個數據庫、集合或查詢結果。mongodump可以通過轉儲oplog來生成一致的數據快照。mongorestore實用程序將數據恢復到新的或現有的數據庫。mongorestore將從mongodump生成的BSON數據庫轉儲中導入內容,並重播oplog。

mongodump只捕獲數據庫中的文檔。產生的備份是空間有效的,但是mongorestore或mongod必須在恢復數據後重建索引。

但實際上,很多線上的MONGODB 系統可能並不是這樣備份和恢復的。


但我們還是先看看相關的命令,對於小型的系統來說還是使用這樣的方式來備份。

備份(J 為操作使用的線程, --gzip 是壓縮)

mongodump --host=192.168.198.180 --port=27027 --username=admin --password=1234.com --authenticationDatabase=admin --gzip --db test -v -j 8 -o /mongodata/backup

MongoDB  備份 導出導入數據的方法和注意事項

數據的恢復

mongorestore --host=192.168.198.181 --port=27027 --username=admin --password=1234.com --authenticationDatabase=admin --db test -v --drop -j 8 --gzip --dir='/mongodata/backup/test'


MongoDB  備份 導出導入數據的方法和注意事項


對於單機來說上面的備份和恢復的方式基本上就滿足了。當然可以寫一個腳本,然後在rsync 到對應的備份存儲的地方就可以。


但實際上很多MONGODB 的使用的方式都是複製集,那具體的複製replica set 是怎麼備份的。

MongoDB  備份 導出導入數據的方法和注意事項


mongodump --uri="mongodb://backup:[email protected]:27027,10.5.1.115:27027,10.5.1.116:27027/DB_AAP_LOG?replicaSet=repl&readPreference=secondary" --gzip -v -j 8 -o /wu


上面的命令就是從MONGODB3.46引入了 uri的方式連接MONGODB ,通過這樣的方式來針對複製集合來進行備份 其中 -j 的方式對數量較多的數據進行備份。由於和--db 命令有衝突,直接可以在備份的指定的認證數據庫就是要備份的數據塊即可。(如有問題請指出)


實際上這裡有一個點,就是MONGODB 是不是也需要類似傳統數據庫的鎖,來將備份的數據的一致性進行一個限制,實際上這裡是有選擇的如果你選擇了 mongodb 備份的時候增加了 --oplog 則會從備份開始添加相關的oplog日誌,在恢復的時候可以使用,這裡我個人認為就類型與 mysqldump 裡面的 --single-transaction 有類似的功效。但需要的是,要對數據庫進行FULL備份的時候才能應用,而不能對數據庫中個別的庫進行備份使用,這是理所當然的數據恢復後,是否需要對索引進行一個確認

MongoDB  備份 導出導入數據的方法和注意事項

下面的腳本可以在MONGODB 中直接運行,並獲取當前數據庫的索引信息


var collectionList = db.getCollectionNames();

for(var index in collectionList){

var collection = collectionList[index];

var cur = db.getCollection(collection).getIndexes();

if(cur.length == 1){

continue;

}

for(var index1 in cur){

var next = cur[index1];

if(next["key"]["_id"] == '1'){

continue;

}

print(

"try{ db.getCollection(\""+collection+"\").ensureIndex("+JSON.stringify(next.key)+",{background:1, unique:" + (next.unique || false) + "" + (next.expireAfterSeconds > 0 ? ", expireAfterSeconds :" + next.expireAfterSeconds : "") + " })}catch(e){print(e)}")}}


另外還有一個問題,就是如果我不備份整個MONGODB 我只備份一個庫,然後想增量怎麼辦,可能就需要你的collection有相關的時間字段,然後export import 根據時間來進行,可能操作會稍微有點複雜。


例如下面的數據中,我們只想根據date 界限將一些數據導出

MongoDB  備份 導出導入數據的方法和注意事項

mongoexport -uXXX -pXXXXX --host 192.168.198.180:27027 -d test -c testData -q '{ date: { $lte: { "$date": "2020-03-30T02:23:25Z" } } }' --out /mongodata/backup/testData.json

MongoDB  備份 導出導入數據的方法和注意事項

這樣我們就導出了你需要的數據

MongoDB  備份 導出導入數據的方法和注意事項


實際上如果用備份的方式,數據是可以壓縮的比較小,但靈活性就相對差一些,導入導出數據的特點就是靈活,但佔用的時間和空間會大。

mongoimport -uXXX -pXXXXX --host 192.168.198.181:27027 -d test -c testData --type json --file='/mongodata/backup/testData.json'

MongoDB  備份 導出導入數據的方法和注意事項

我們用上面的命令就將對應的數據導入

MongoDB  備份 導出導入數據的方法和注意事項


這裡估計很多同學都會有疑問,mongodump mongorestore 和 mongoimport mongexport 比較後者靈活性在哪裡,

舉一個例子,當數據從一個表,要進入另一個表,並且有些字段還有取捨,同時由於數據可能有重複性,也就是_id 可能有重複的可能,這時你能選擇的大概率是 mongoimport mongoexport , 通過下圖的選項你可以讓那些重複可能有衝突的數據“安安靜靜”的聽你的指揮,至少你可以有選擇,如果你使用dump resotre 那就........

MongoDB  備份 導出導入數據的方法和注意事項


在回到備份,如果你的數據庫比較大,通過這樣的方法來進行備份,那就.... 比較慢,是不是有更好的方式來對數據庫進行備份,由於MONGODB 本身不具有強事務性,所以在MONGODB 備份中會經常用到這樣一個命令,從MONGODB 3.2開始,就支持卷備份了。

MongoDB  備份 導出導入數據的方法和注意事項

就是下面這個命令了,在db.fsyncLock() 將你的MONGODB 的寫鎖住,然後就可以開始拷貝你的文件了,將你的文件都拷貝走,當然你可以LVM 等方式,具體的按你心願,

在拷貝完畢後,在直接,鍵入db.fsyncUnlock() 解鎖,數據就可以繼續寫入了。

MongoDB  備份 導出導入數據的方法和注意事項


實際上大部分的MONOGDB的數據庫的(大容量)的備份都是這樣的方式,尤其集群的方式中將從庫鎖定,然後拷貝從庫的數據到備份位置,然後解開鎖,但需要注意的是,你在操作的過程中的時間,和不要忘記你的數據庫在被鎖定,以及報警等方方面面的問題,你都需要去處理。


實際上對於MONGODB 的備份還有一種想法,就是直接在複製集的基礎上,建立一個備份節點,我知道這樣的想法可能做傳統數據庫的DB們不是很認同,如果人家的數據要回滾怎麼辦,如果數據要存檔怎麼辦。當然也可以有延遲庫(使用過MYSQL的小夥伴應該對這個概念不會陌生)


說到這裡還是一個我的口頭禪,任何事情都要看你的業務邏輯,如果你的MONGODB 僅僅是一個流水賬,和一些日誌的話,是否對這些東西必須要進行備份,另外備份的意義在哪裡,例如如果你的數據庫是 cassandra 那上百個節點的時候,怎麼備份呢???? 所以不同的數據庫可能會顛覆你長久以來的一些對數據庫的操作的方法和態度,這世界變化快,follow it . (如果在生產時間備份,強烈建議全部在複製集合的從庫上進行備份)


MongoDB  備份 導出導入數據的方法和注意事項


分享到:


相關文章: