本文簡單介紹mongodb時間點恢複的過程:
1.首先建立hezi集合,并插入10000條資料;
MongoDB Enterprise liuhe_rs:PRIMARY>use liuwenhe
MongoDB Enterprise liuhe_rs:PRIMARY>for (
var i = 0; i < 100000; i++) {
db.hezi.insert({id: i});
}
MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.count();
100000
2.執行備份操作,使用參數 --oplog ,會在備份路徑下産生oplog.bson檔案
[mongod@beijing-fuli-hadoop-01 backup]$ mongodump -h 10.9.21.179 -u liuwenhe -p
liuwenhe --authenticationDatabase admin --oplog -o /data/mongodb/backup/
假裝置份開始時間為 A 結束時間為B
3.等備份完成後,如果此時業務又insert了資料:
MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.insert({id: 100001});
WriteResult({ "nInserted" : 1 })
100001
4.在時間 C點,模拟誤删除操作
MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.remove({})
WriteResult({ "nRemoved" : 100001 })
5.那麼怎麼來恢複這個表呢?
這種情況下,應該首先停止業務,避免由于業務量大,導緻把oprlog給覆寫了,因為如果
oprlog被覆寫了,那麼你就無法恢複出db.hezi.insert({id: 100001})這條資料,因為這條資料
是在你備份完成後插入的資料,是以你需要立刻把oplog.rs集合給dump出來以便于進行時
間點恢複,
是以分兩種情況具體如下:
情況一:
你備份開始的時間點A 到 你誤删除的時間點C 這段時間的oplog.rs的資料沒有被覆寫
那麼就肯定能恢複出所有的資料!直接用你後來備份的oplog.rs替換你之前全備份的産生的
oplog.bson檔案!
情況二:(分成兩種情況)
如果你備份開始的時間點A 到 你誤删除的時間點C 這段時間的oplog.rs的資料被覆寫了,
那麼你就隻能先恢複你的全備,然後再從oplog.rs裡面盡可能找到更多的關于這個集合的
操作,然後應用,能不能全部恢複出資料,就看運氣了,這裡又有兩種情況:
情況1:備份結束B到誤删除C 這段時間内的oplog.rs沒有被覆寫,那麼就可以恢複出所有的資料
情況2:備份結束B到誤删除C 這段時間内的oplog.rs被覆寫,那麼就隻能期待關于這個
賣手遊集合的操作
的oplog沒有被覆寫,這樣才能恢複出所有的資料!
怎麼去分辨到底有沒有被覆寫呢?
首先在你備份的機器上看,可以看出oplogs的開始和結束時間,當然這不一定準确,
MongoDB Enterprise liuhe_rs:PRIMARY> rs.printReplicationInfo()
configured oplog size: 51200MB
log length start to end: 1299939secs (361.09hrs)
oplog first event time: Sat Nov 16 2019 16:53:17 GMT+0800 (CST)
oplog last event time: Sun Dec 01 2019 17:58:56 GMT+0800 (CST)
now: Sun Dec 01 2019 17:59:02 GMT+0800 (CST)
最好還是從你單獨備份集合oplog.rs的備份檔案
oplog.rs.bson中去判斷:
格式化檔案oplog.rs.bson,以便于檢視時間
[mongod@beijing-fuli-hadoop-04 local]$ bsondump oplog.rs.bson >12
看備份中的oplog的開始時間
[mongod@beijing-fuli-hadoop-04 local]$ cat 12 | head
{"ts":{"$timestamp":{"t":1575040546,"i":1}},"t":{"$numberLong":"7"},"h":{"$numberLong":"-8378285387564165709"},"v":2,"op":"n","ns":"","wall":{"$date":"2019-11-29T15:15:46.661Z"},"o":{"msg":"Reconfig set","version":26}}
看備份中的oplog的結束時間
[mongod@beijing-fuli-hadoop-04 local]$ cat 12 | tail -n 1
同理再去檢視全備份的産生的oplog.bson中的開始時間和結束時間!就可以判斷出有沒有被覆寫了!
情況1:
1)dump出集合oplog.rs的資料
[mongod@beijing-fuli-hadoop-01 local]$ mongodump -h 10.9.21.179 -u liuwenhe -p liuwenhe --authenticationDatabase admin -d local -c oplog.rs -o /data/mongodb/liuwenhe/
[mongod@beijing-fuli-hadoop-01 local]$ pwd
/data/mongodb/liuwenhe/local
[mongod@beijing-fuli-hadoop-01 local]$ ll
total 60308
-rw-rw-r-- 1 mongod mongod 61751065 Nov 29 19:42
oplog.rs.bson
-rw-rw-r-- 1 mongod mongod 124 Nov 29 19:42 oplog.rs.metadata.json
2)然後找到删除hezi集合的開始時間, 當你删除某個集合的時候,她在oplogs中是一條一條的删除的!這個你可以使用bsondump格式化看看!
[mongod@beijing-fuli-hadoop-01 local]$ bsondump oplog.rs.bson | grep "\"op\":\"d\"" | grep liuwenhe.hezi |head
{"ts":{"$timestamp":{"t":1575025894,"i":1}},"t":{"$numberLong":"6"},"h":{"$numberLong":"2211936654694340159"},"v":2,"op":"d","ns":"liuwenhe.hezi","ui":{"$binary":"GG4MuSZBQpm4anq5TBp00Q==","$type":"04"},"wall":{"$date":"2019-11-29T11:11:34.499Z"},"o":{"_id":{"$oid":"5de0fb7cb54dce214bb40c7b"}}}
3)需要把 前面備份的oplog.rs.bson檔案替換全備份的檔案中的oplog.bson檔案,
這裡的oplog.rs.bson其實就是我們需要的oplog.bson。是以把它重命名後放到合适的位置!
[mongod@beijing-fuli-hadoop-03 /data/mongodb/backup/backup]$ rm -f oplog.bson
[mongod@beijing-fuli-hadoop-03 /data/mongodb/backup/backup]$mv oplog.rs.bson oplog.bson
其中oplog.rs.bson是你前面單獨備份的oplog.rs, 而oplog.bson是你全備份中帶參數
--oplog産生的檔案;
4)在另一個空閑執行個體上恢複出之前的全備份:
先把備份從21.114copy到21.115特定的目錄中:
scp -r backup/ [email protected]:/data/mongodb/backup/
然後進行恢複:
[mongod@beijing-fuli-hadoop-03 /data]$ mongorestore -h 10.9.21.115 -u liuwenhe -p liuwenhe --oplogReplay --oplogLimit "
1575025894
:1" --authenticationDatabase admin --dir /data/mongodb/backup/backup/
其中
1575025894即是$timestamp中的"t",
1即是$timestamp中的"i"。這樣配置後oplog将會
重放到這個時間點以前,即正好避開了第一條删除語句及其後面的操作,資料庫停留在災難
前狀态
驗證确實恢複出來了:
MongoDB Enterprise > db.hezi.count()
5)把恢複出來的資料在恢複到生産上去:
在21.115上備份:
mongodump -h 10.9.21.115 -u liuwenhe -p liuwenhe -d liuwenhe -dliuwenhe -c hezi --authenticationDatabase admin -o /data/mongodb/
在21.115上直接恢複,前提網絡通,如果不通的話,先把備份檔案copy到生産上。然後恢複:
[mongod@beijing-fuli-hadoop-04 li]$ mongorestore -h 10.9.21.114 -u liuwenhe -p liuwenhe -d liuwenhe -c hehe --noIndexRestore --authenticationDatabase admin --dir /data/mongodb/backup/li/hezi.bson
情況2中的第一種情況:
備份結束B到誤删除C 這段時間内的oplog.rs沒有被覆寫,那麼就可以恢複出所有的資料,具體
恢複過程如下:
1.恢複一緻性全備份:
[mongod@beijing-fuli-hadoop-03 /data]$ mongorestore -h 10.9.21.115 -u liuwenhe -p liuwenhe --oplogReplay --authenticationDatabase admin --dir /data/mongodb/backup/backup/
2.然後再繼續增量恢複oplog,從備份的oplog.rs檔案中找到删除hezi這個集合的時間點,因為opglog
的幂等性,可以重複執行也不會造成資料不一緻,是以沒必要在導出oplog.rs的時候選擇增量導出;
mongorestore -h 10.9.21.115 -u liuwenhe -p liuwenhe --oplogReplay --oplogLimit "
:1" --authenticationDatabase admin --dir /data/mongodb/backup/backup/local/oplog.rs.bson
情況2中的第二種情況:
備份結束B到誤删除C 這段時間内的oplog.rs被覆寫,那麼就隻能期待關于這個集合的操作
的oplog沒有被覆寫,這樣才能恢複出所有的資料!坦白講這種情況下,沒法确認到底關于
這個集合的操作的oplogs有沒有被覆寫,隻能先恢複看了,過程同情況2中的第一種情況;
綜上所述:
mongodb的時間點恢複的過程類似于mysql借助binlog的過程,但是差別是
mysql需要找到具體的 gtid點,增量恢複,但是mongodb的oplog是可以多次執行,這樣就使得
mongodb 借助oprlog的時候操作簡單些;