2.MongoDB 4.2副本集环境基于时间点的恢复

前端之家收集整理的这篇文章主要介绍了2.MongoDB 4.2副本集环境基于时间点的恢复前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

image



(一)MongoDB恢复概述
对于任何数据库,如果要将数据库恢复到过去的任意时间点,否需要有过去某个时间点的全备+全备之后的重做日志。
接下来根据瑞丽航空的情况进行概述:
全备:每天晚上都会进行备份;
重做日志备份:MongoDB只有开启主从复制或者副本集时才会开启重做日志,主从复制存放在local数据库下的“oplog.$main”集合中,复制集的日志存放在local数据库下的oplog.rs集合中,该集合是一个上限集合,当达到固定大小时,最老的记录会被自动覆盖。因此需要注意,MongoDB的重做日志并不会一直保存着,能否恢复到故障点,完全取决于日志是否完整。


(二)基础环境
本次测试备份恢复使用的是MongoDB 4.2版本副本集环境,副本集配置如下:

rstest:PRIMARY> rs.config()
 {
     "_id" : rstest",version2protocolVersion" : NumberLong(1),1)">writeConcernMajorityJournalDefault" : truemembers : [
         {
             0host192.168.10.41:27017arbiterOnlyfalsebuildIndexeshiddenpriority3tags : {            
             },1)">slaveDelayvotes
         },{
             192.168.10.42:27017 : {        
             },1)">192.168.10.43:27017 : {                
             },1)">
         }
     ],1)">settings : {
         chainingAllowedheartbeatIntervalMillis2000heartbeatTimeoutSecs10electionTimeoutMillis10000catchUpTimeoutMillis" : -catchUpTakeoverDelayMillis30000getLastErrorModes : {    
         },1)">getLastErrorDefaults : {
             wwtimeoutreplicaSetId" : ObjectId(5f32312d4911b68cdaac02a6)
     }
 }
 rstest:PRIMARY>


(三)确认日志保存情况
oplog是一个上限集合,当数据量达到一定大小后,MongoDB会自动清理oplog日志信息,为了保证恢复能够正常进行,需要确认日志的时间是否符合还原需求。简单来说,oplog应该保存着自上一次备份以来的所有日志。可以使用下面方法来确认最早的oplog。
方法:查看主从复制信息
在主节点查看日志信息,可以看到oplog日志大小,因为oplog是一个固定大小的集合,所以还可以看到日志的开始、结束时间、oplog的时间差等。

db.printReplicationInfo() configured oplog size: 1687.392822265625MB log length start to end: 246186secs (68.39hrs) oplog first event time: Tue Aug 11 2020 13:48:29 GMT+0800 (CST) oplog last event time: Fri Aug 14 10:11:35 GMT+ (CST) now: Fri Aug 36 GMT+0800 (CST)


(四)模拟将MongoDB恢复到任意时间点
(4.1)案例一:将整个实例恢复到某个时间点
(4.1.1)故障场景描述
业务人员发现多个MongoDB数据库均存在数据错误的情况,需要将全部数据恢复到过去的某个时刻。


(4.1.2)数据恢复方法描述
只要确定了恢复时间点,就可以使用完全备份+oplog备份,将数据恢复到过去的某个时刻。


(4.1.3)恢复过程
STEP1:模拟业务正常运行,数据正常进入MongoDB数据库

use db1
db.db1test.insert({id:1,name:'a'})
db.db1test.insert({2,1)">b})

use db2
db.db2test.insert({11,1)">aa})
db.db2test.insert({22,1)">bb'})

STEP2:执行完整备份

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -o /root/backup/full

STEP3:再次模拟业务正常运行,数据正常进入MongoDB数据库

3,1)">c33,1)">cc'})

最终数据如下:

use db1 switched to db db1 rstest:PRIMARY> db.db1test.find() { 5f35f4ed09eccc387e65cd86"),idname } { 5f35f4ed09eccc387e65cd875f35f57409eccc387e65cd8a } rstest:PRIMARY> use db2 switched to db db2 rstest:PRIMARY> db.db2test.5f35f4ed09eccc387e65cd885f35f4ee09eccc387e65cd895f35f57509eccc387e65cd8b" }

STEP4:模拟数据误操作

@H_403_332@# db1的db1test集合id增加100 use db1 db.db1test.update({},{$inc:{":100}},{multi:}) @H_403_332@# db2的db2test集合被删除 use db2 db.db2test.drop()

错误执行之后的结果:

101,1)">102,1)">103,1)">() rstest:PRIMARY>

要求把所有数据库的数据恢复到STEP4之前的状态。

STEP5:停止业务,不再往数据库写数据

STEP6:备份日志。可以备份部分日志,也可以备份全部日志

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -d local -c oplog.rs -o /root/backup/oplog/

STEP7:确认数据异常时间点,对oplog集合进行分析

use local db.oplog.rs.( { $and : [ {ns" : /db1/},{opu } ] } ).sort({ts:1})

查询结果如下,可以确认,开始对db1.db1test集合更新的时间为Timestamp(1597371835,2)

/* 1 */ { ts" : Timestamp(1597371835,1)">t7hvdb1.db1testui" : UUID(b3566a31-f6c1-4052-82a9-90f70728c41co2 : { ) },1)">wall" : ISODate(2020-08-14T02:23:55.576Zo$v$set : { 101.0 } } } 2 2020-08-14T02:23:55.578Z102.0 3 4103.0 } } }

STEP8:执行完全备份的恢复
需要注意,考虑是否需要使用"--drop"选项,如果不用该选项,会保留集合中当前的数据,如果使用了drop选项,在导入集合时会先删除集合。这里使用该选项

mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 --drop  /root/backup/full/

确认全量恢复的数据,已经恢复回来

} rstest:PRIMARY> } rstest:PRIMARY>

STEP9:使用oplog执行增量恢复
在恢复oplog之前,需要对其格式进行处理,否则会报错

[root@node1 local]# mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 --oplogReplay --oplogLimit 1597371835:2" /root/backup/oplog/local
2020-08-14T10:44:45.120+    preparing collections to restore from
0800    dont know what to do with file "/root/backup/oplog/local/oplog.rs.bson",skipping...
t know what to do with file "/root/backup/oplog/local/oplog.rs.Metadata.json",1)">0800    Failed: no oplog file to replay; make sure you run mongodump with --oplog
0800    0 document(s) restored successfully.  document(s) Failed to restore.

需要把oplog.rs.Metadata.json 文件删除,把oplog.rs.bson名字改为oplog.bson

[root@node1 local]# ls
oplog.rs.bson  oplog.rs.Metadata.json
[root@node1 local]# pwd
/root/backup/oplog/local
[root@node1 local]# rm -rf oplog.rs.Metadata.json 
[root@node1 local]# mv oplog.rs.bson oplog.bson
[root@node1 local]# 
 oplog.bson

后执行oplog增量恢复即可

@H_403_332@# 权限有问题,lijiaman用户具有root角色 mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=local @H_403_332@# 执行成功 [root@node1 local]# mongorestore --authenticationDatabase admin -uroot2 -p123456 --port=" /root/backup/oplog/local

关于恢复权限,在MongoDB2.7也有相同的问题,见上一篇文档

STEP10:确认数据恢复情况,发现数据以及恢复到了STEP4之前的状态

rstest:PRIMARY> } rstest:PRIMARY>

至此恢复结束。


(4.2)案例二:误删除某个DB,对单个DB进行恢复
通常,每个DB承载不同的业务,相互之间没有关系,如果出现故障,往往会表现在某个DB上,因此,如果出现故障,只对相应的DB进行恢复,那将减小对业务的影响。
(4.2.1)故障场景描述
假设业务运行过程中,数据库db3被人误删除了,我们需要对db3进行恢复,并且不能影响到其它的DB业务。


(4.2.2)数据恢复方法描述
可以在当前实例上进行恢复,也可以新启动一个mongod实例,用于数据恢复,我们采用新的mongod实例来恢复数据。
1.首先新启动一个mongod实例;
2.将已有的完全备份恢复到新的实例上;
3.备份oplog,只备份db3的oplog,其它数据库的不备份;
4.使用oplog将数据库恢复到删除之前;
5.检查db3数据库的数据,确认是否恢复回来;
6.如果第5步没有问题,mongodump导出db3数据库,然后倒入到生产环境中。


(4.2.3)恢复过程
use db3 db.db3test.insert({111,1)">aaa}) db.db3test.insert({222,1)">bbb333,1)">ccc444,1)">ddd555,1)">eee666,1)">fff

rstest:PRIMARY> db.db3test.5f35fff809eccc387e65cd8c5f35fff809eccc387e65cd8d5f35fff909eccc387e65cd8e5f3600b309eccc387e65cd8f5f3600b309eccc387e65cd905f3600b409eccc387e65cd91 db
db3
rstest:PRIMARY> db.dropDatabase()
{
    droppeddb3ok$clusterTimeclusterTime1597374734,1)">signaturehash" : BinData(0,1)">0uoicASFK0ppoNhIEuURwElt7Qk=keyId6859599294731649027)
        }
    },1)">operationTime)
}
rstest:PRIMARY>

接下来执行恢复操作。

STEP5:在发现误操作之后,首先应该备份oplog,这里只涉及到db3数据库,只要备份db3的oplog即可,这样可以加快备份恢复速度

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -d local -c oplog.rs -q {"ns":{"$regex":"db3"}}'  -o /root/backup/oplog/

STEP6:先执行完全恢复

mongorestore --authenticationDatabase admin -ulijiaman -plijiaman  --port=27017 -d db3 /root/backup/full/db3

执行恢复后,db3数据已经恢复到了全备时的状态

show dbs admin .000GB config .000GB db1 .000GB db2 .000GB db3 .000GB lijiamandb .000GB local .002GB maxiangqian .000GB rstest:PRIMARY> use db3 switched to db db3 rstest:PRIMARY> show collections db3test rstest:PRIMARY> db.db3test.STEP7:使用oplog恢复到drop操作之前
先确认drop db3数据库的时间点:Timestamp(1597374734,1)">use local db.oplog.rs." : {$regex}},1)">" : {dropDatabase}} ] } ).1})

结果如下

db3.$cmd2020-08-14T03:12:14.206Z } }

执行增量恢复:

@H_403_332@# 先处理oplog,删除文件oplog.rs.Metadata.json,修改oplog.rs.bson为oplog.bson [root@node1 local]# oplog.rs.bson oplog.bson [root@node1 local]# oplog.bson @H_403_332@# 执行恢复 mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 --oplogReplay --oplogLimit 1597374734:1" /root/backup/oplog/local

特别注意:这里发现,oplogLimit参数,在MongoDB 2.7版本中不包含后面的时间点,在4.2里面包含后面的时间点。如果我使用时间Timestamp()来作为恢复点,则发现数据库恢复完成又被删除了。

检查数据是否已经恢复,可以确认,数据已经恢复回来

" }


(4.3)案例三:误操作某个集合,对单个集合进行恢复
(4.3.1)故障场景描述
业务人员执行误删操DBA对数据进行恢复,详细过程如下:
T1~T2:业务正常运行,数据正常进入数据库
T2:使用mongodump执行数据库完全备份
T2~T4:业务正常运行,数据正常进入数据库
T4:用户删除数据
T4~T6:业务还在运行,但是已经出现问题,如此时还能正常插入数据,但是查询、更新、删除数据存在找不到数据的错误
T6:DBA介入数据恢复


(4.3.2)数据恢复方法描述
可以在当前实例上进行恢复,也可以新启动一个mongod实例,用于数据恢复,我们在上一个例子中已经使用新建mongod实例的方式来恢复数据,本次实验我们直接在生产实例上进行恢复。
1.执行完全恢复,使用完全备份,将数据库恢复到T2时刻;
2.找到T4时刻故障之前的时间,从而确定T2~T4之间的oplog日志。结合T2时刻的全备+ T2~T4之间的oplog日志,实现数据恢复;(备注:这里不需要去确认T2之后的日志开始时间,在使用oplog恢复数据时,是通过唯一编号“_id”来操作数据的,oplog可能从全备份之前的任意时间开始,但是并不影响数据的正确性)。
3.找到T4时刻故障之后的时间,备份oplog。
4.使用oplog,实现T4~T6时间段的恢复。


(4.3.3)恢复过程
use db4 db.db4test.insert({1111,1)">aaaa}) db.db4test.insert({2222,1)">bbbb3333,1)">cccc4444,1)">dddd5555,1)">eeee6666,1)">ffff

rstest:PRIMARY> db.db4test.5f36267a09eccc387e65cd925f36267a09eccc387e65cd935f36267b09eccc387e65cd945f3628c809eccc387e65cd955f3628c809eccc387e65cd965f3628c909eccc387e65cd97STEP4:模拟数据误操作,删除2条数据

rstest:PRIMARY> db.db4test.remove({id:{$gt:4444}})
WriteResult({ nRemoved })

rstest:PRIMARY> db.db4test.STEP5:再次模拟业务正常运行,数据正常进入MongoDB数据库

7777,1)">gggg8888,1)">hhhh9999,1)">kkkk5f3639a009eccc387e65cd985f3639a009eccc387e65cd995f3639a109eccc387e65cd9a" }

此时,我们发现id为5555和6666的数据是被误删除的,需要恢复回来,并且要保留执行删除命令之后的数据。

STEP6:在发现误操作之后,首先应该备份oplog,这里只涉及到db4.db4test集合,只要备份该集合的oplog即可,这样可以加快备份恢复速度

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -d local -c oplog.rs' -q {"ns":"db4.db4test"}STEP7:对该集合执行完全恢复操作

27017 -d db4 -c db4test /root/backup/full/db4/db4test.bson

STEP8:使用oplog,对该集合执行增量恢复操作
先查看对db4.db4test集合执行删除的开始时间Timestamp(1597389188,1)

" : /db4.db4test/d}) 1597389188,1)">db4.db4test75507280-3f74-4c17-a3f7-46ce7087c08a2020-08-14T07:13:08.162Z) } } ) } }

执行增量恢复:

@H_403_332@# 先处理oplog,删除文件oplog.rs.Metadata.json,修改oplog.rs.bson为oplog.bson [root@mongo1 local]# local [root@mongo1 local]# rf oplog.rs.Metadata.json [root@mongo1 local]# oplog.rs.bson oplog.bson [root@mongo1 local]# oplog.bson @H_403_332@# 执行恢复 mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=1597389188:1" /root/backup/oplog/local

STEP9:查看数据是否恢复,确认已经完全恢复回来

" }


【完】


相关文档:

1.MongoDB 2.7主从复制(master –> slave)环境基于时间点的恢复  
2.MongoDB 4.2副本集环境基于时间点的恢复


3.MongoDB恢复探究:为什么oplogReplay参数只设置了日志应用结束时间oplogLimit,而没有设置开始时间?

猜你在找的MongoDB相关文章