本文简单介绍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 })
MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.count();
100001
4.在时间 C点,模拟误删除操作
MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.remove({})
WriteResult({ "nRemoved" : 100001 })
MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.count();
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
{"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.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/ mongod@10.9.21.115:/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()
100000
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 "
1575025894
: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的时候操作简单些;