MongoDB數(shù)據(jù)庫的備份與恢復詳解
MongoDB是怎么實現(xiàn)數(shù)據(jù)的備份與恢復,故障切換以及數(shù)據(jù)庫服務器的負載均衡等功能的呢?本文我們就介紹這些知識。
備份與恢復
在創(chuàng)建MongoDB服務的時候,通過--dbpath指定目錄就是存放mongdb數(shù)據(jù)庫文件目錄,我們可以通過復制這些文件實現(xiàn)數(shù)據(jù)庫的冷備,但是這種方式不太安全。因此在冷備前,要關閉服務器,這個在第一節(jié)中介紹過平滑關閉server的命令。
- >use admin
- >db.shutdownServer()
或者可以通過fsync方式使MongoDB將數(shù)據(jù)寫入緩存中,然后再復制備份
- >use admin
- >db.runCommand({"fsync":1,"lock":1})
這個時候我往test.foo 插入了一條數(shù)據(jù) f:6 ,在執(zhí)行db.foo.find()后,并沒有查到這條記錄,說明記錄沒有直接寫入數(shù)據(jù)庫,而是被緩沖到緩存中了。
備份完后,要解鎖(防止這個時候停電或其它原因,導致未緩存中的數(shù)據(jù)丟失)。
- >use admin
- >db.$cmd.sys.unlock.findOne()
- >db.currentOp() 如果currentOp 只返回{"inprog":[]}結果,說明解鎖成功。
解鎖后,緩存中的數(shù)據(jù)會寫入數(shù)據(jù)庫文件中,我們?nèi)ゲ樵僨oo結果。
上面是冷備的方式,我們可以在不停止服務的情況下,使用MongoDB提供的兩個工具來實現(xiàn)備份和恢復。這個兩個工具在MongoDB的bin目錄下可以看到:mongodump.exe/mongorestor.exe
mongodump.exe備份的原理是通過一次查詢獲取當前服務器快照,并將快照寫入磁盤中,因此這種方式保存的也不是實時的,因為在獲取快照后,服務器還會有數(shù)據(jù)寫入,為了保證備份的安全,同樣我們還是可以利用fsync鎖使服務器數(shù)據(jù)暫時寫入緩存中。
備份命令:
- ......bin>mongodump -d test -o backup //( backup是備份目錄,默認創(chuàng)建到bin目錄)
恢復命令: (可以在恢復前往foo表插入一條記錄 g:7)
- .....bin>mongorestore -d test --drop backup/test/
看一下運行結果:
以上就是mongodb的備份和恢復過程。當數(shù)據(jù)庫文件出現(xiàn)問題或者損壞時,MongoDB還提供了修復數(shù)據(jù)文件的命令。
在啟動mongod服務時通過--repair 修改:
- ....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\master" --repair
另外我們也可以在mongo shell 中修復正在運行的數(shù)據(jù)庫存
- >use test
- >db.repairDataBase()
#p#
接下來我們在來看一下另外二種讀擴展式的備份機制。
Master-Slave
主從復制模式:即一臺主寫入服務器,多臺從備份服務器。從服務器可以實現(xiàn)備份,和讀擴展,分擔主服務器讀密集時壓力,充當查詢服務器。但是主服務器故障時,我們只能手動去切換備份服務器接替主服務器工作。這種靈活的方式,使擴展多如備份或查詢服務器相對比較容易,當然查詢服務器也不是無限擴展的,因為這些從服務器定期在輪詢讀取主服務器的更新,當從服務器過多時反而會對主服務器造成過載。
我們以之前創(chuàng)建的端口為27017做為主服務器,再創(chuàng)建個端口為27018從服務器
重新啟動27017為主服務器 --master 主服務器
- ....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\master" --master
創(chuàng)建27018為從服務器 --slave 從服務器 --source 指定主服務器
- ....bin>mongod --port 27018 --dbpath "C:\Program Files\mongodb\data\dbs\slave27018" --slave --source localhost:27017
主服務器可以通過自己local庫的slave集合查看從服務器列表
從服務器可以通過自己local庫的source集合查看主服務器信息或維護多個主服務器。 (一個slave服務器可以服務多個master服務器)
或者我們可以通過http console查看狀態(tài)
Replica Sets
副本集模式:具有Master-Slave模式所有特點,但是副本集沒有固定的主服務器,當初始化的時候會通過多個服務器投票選舉出一個主服務器。當主服務器故障時會再次通過投票選舉出新的主服務器,而原先的主服務器恢復后則轉為從服務器。Replica Sets的在故障發(fā)生時自動切換的機制可以極時保證寫入操作。
創(chuàng)建多個副本集節(jié)點 --replSet (注意要區(qū)分大小寫,官方建議命名空間使用IP地址)
- ....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27017" --port 27017 --replSet replset/127.0.0.1:27018
- ....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27018" --port 27018 --replSet replset/127.0.0.1:27017
- ....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27019" --port 27019 --replSet replset/127.0.0.1:27017
首先建立3個是為了投票不會沖突,當服務器為偶數(shù)時可能會導致無法正常選舉出主服務器。
其次上面3個replset 節(jié)點沒有全部串聯(lián)起來,是因為replset 有自檢測功可以自動搜索連接其它服務器。
完成上面的工作后,要初始化副本集,隨便連接一臺服務器執(zhí)行以下命令 (priority 0~1,被選為主服務器的優(yōu)先級)
- >use admin
- >db.runCommand(
- {"replSetInitiate":{
- "_id":"replset",
- "members":[
- {
- "_id":1,
- "host":"127.0.0.1:27017",
- "priority":1
- },
- {
- "_id":2,
- "host":"127.0.0.1:27018",
- "priority":1
- },
- {
- "_id":3,
- "host":"127.0.0.1:27019",
- "priority":1
- }]}}
- )
查看結果,可以看出127.0.0.1:27017 被自動選為replSet:Primary>
在增加一個從服務器節(jié)點
- ....bin>mongod --dbpath "C:\Program Files\mongodb\data\dbs\replset27020" --port 27020 --replSet replset/127.0.0.1:27017
通過rs.add命令往system.replset添加新的從服務器成員
- rs.add("127.0.0.1:27020"); 或者rs.add({"_id":4,"host":"127.0.0.1:27020"})
這里在簡單的介紹一下Master Slave/ Replica Sets 備份機制,這兩種模式都是基于主服務器的oplog 來實現(xiàn)所有從服務器的同步。
oplog記錄了增刪改操作的記錄信息(不包含查詢的操作),但是oplog有大小限制,當超過指定大小,oplog會清空之前的記錄,重新開始記錄。
Master Slave方式主服備器會產(chǎn)生 oplog.$main 的日志集合。
Replica Sets 方式 所有服務器都會產(chǎn)生oplog.rs 日志集合。
兩種機制下,所有從服務器都會去輪詢主服務器oplog日志,若主服務器的日志較新,就會同步這些新的操作記錄。但是這里有個很重要的問題,從服務器由于網(wǎng)絡阻塞,死機等原因無法極時同步主服務器oplog記錄:一種情況 主服務器oplog不斷刷新,這樣從服務器永遠無法追上主服務器。另外一種情況,剛好主服務器oplog超出大小,清空了之前的oplog,這樣從服務器就與主服務器數(shù)據(jù)就可能會不一致了,這第二種情況,我是推斷的,沒有證實。
另外要說明一下Replica Sets 備份的缺點,當主服務器發(fā)生故障時,一臺從服務器被投票選為了主服務器,但是這臺從服務的oplog 如果晚于之前的主服務器oplog的話,那之前的主服務器恢復后,會回滾自己的oplog操作和新的主服務器oplog保持一致。由于這個過程是自動切換的,所以在無形之中就導致了部分數(shù)據(jù)丟失。
關于MongoDB備份與恢復的知識就介紹到這里了,希望能夠帶給您收獲。
【編輯推薦】