(一)MongoDB恢复概述


对于任何数据库,如果要将数据库恢复到过去的任意时间点,否需要有过去某个时间点的全备+全备之后的重做日志。

接下来根据瑞丽航空的情况进行概述:

全备:每天晚上都会进行备份;

重做日志备份:MongoDB只有开启主从复制或者副本集时才会开启重做日志,主从复制存放在local数据库下的“oplog.$main”集合中,复制集的日志存放在local数据库下的oplog.rs集合中,该集合是一个上限集合,当达到固定大小时,最老的记录会被自动覆盖。因此需要注意,MongoDB的重做日志并不会一直保存着,能否恢复到故障点,完全取决于日志是否完整。

(二)基础环境

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

rstest:PRIMARY> rs.config()
{
"_id" : "rstest",
"version" : 2,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "192.168.10.41:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 3,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "192.168.10.42:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "192.168.10.43:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5f32312d4911b68cdaac02a6")
}
}
rstest:PRIMARY>


(三)确认日志保存情况


oplog是一个上限集合,当数据量达到一定大小后,MongoDB会自动清理oplog日志信息,为了保证恢复能够正常进行,需要确认日志的时间是否符合还原需求。简单来说,oplog应该保存着自上一次备份以来的所有日志。可以使用下面方法来确认最早的oplog。

方法:查看主从复制信息

在主节点查看日志信息,可以看到oplog日志大小,因为oplog是一个固定大小的集合,所以还可以看到日志的开始、结束时间、oplog的时间差等。

rstest:PRIMARY> 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 2020 10:11:35 GMT+0800 (CST)
now: Fri Aug 14 2020 10:11: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({id:2,name:'b'}) use db2
db.db2test.insert({id:11,name:'aa'})
db.db2test.insert({id:22,name:'bb'})

STEP2:执行完整备份

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

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

use db1
db.db1test.insert({id:3,name:'c'}) use db2
db.db2test.insert({id:33,name:'cc'})

最终数据如下:

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 1, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 2, "name" : "b" }
{ "_id" : ObjectId("5f35f57409eccc387e65cd8a"), "id" : 3, "name" : "c" } rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd88"), "id" : 11, "name" : "aa" }
{ "_id" : ObjectId("5f35f4ee09eccc387e65cd89"), "id" : 22, "name" : "bb" }
{ "_id" : ObjectId("5f35f57509eccc387e65cd8b"), "id" : 33, "name" : "cc" }

STEP4:模拟数据误操作

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

错误执行之后的结果:

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 101, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 102, "name" : "b" }
{ "_id" : ObjectId("5f35f57409eccc387e65cd8a"), "id" : 103, "name" : "c" } rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
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.find(
{
$and : [
{"ns" : /db1/},
{"op" : "u" }
]
}
).sort({ts:1})

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

/* 1 */
{
"ts" : Timestamp(1597371835, 2),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "u",
"ns" : "db1.db1test",
"ui" : UUID("b3566a31-f6c1-4052-82a9-90f70728c41c"),
"o2" : {
"_id" : ObjectId("5f35f4ed09eccc387e65cd86")
},
"wall" : ISODate("2020-08-14T02:23:55.576Z"),
"o" : {
"$v" : 1,
"$set" : {
"id" : 101.0
}
}
}
/* 2 */
{
"ts" : Timestamp(1597371835, 3),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "u",
"ns" : "db1.db1test",
"ui" : UUID("b3566a31-f6c1-4052-82a9-90f70728c41c"),
"o2" : {
"_id" : ObjectId("5f35f4ed09eccc387e65cd87")
},
"wall" : ISODate("2020-08-14T02:23:55.578Z"),
"o" : {
"$v" : 1,
"$set" : {
"id" : 102.0
}
}
}
/* 3 */
{
"ts" : Timestamp(1597371835, 4),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "u",
"ns" : "db1.db1test",
"ui" : UUID("b3566a31-f6c1-4052-82a9-90f70728c41c"),
"o2" : {
"_id" : ObjectId("5f35f57409eccc387e65cd8a")
},
"wall" : ISODate("2020-08-14T02:23:55.578Z"),
"o" : {
"$v" : 1,
"$set" : {
"id" : 103.0
}
}
}

STEP8:执行完全备份的恢复

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

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

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

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 1, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 2, "name" : "b" }
rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd88"), "id" : 11, "name" : "aa" }
{ "_id" : ObjectId("5f35f4ee09eccc387e65cd89"), "id" : 22, "name" : "bb" }
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+0800 preparing collections to restore from
2020-08-14T10:44:45.120+0800 don't know what to do with file "/root/backup/oplog/local/oplog.rs.bson", skipping...
2020-08-14T10:44:45.120+0800 don't know what to do with file "/root/backup/oplog/local/oplog.rs.metadata.json", skipping...
2020-08-14T10:44:45.120+0800 Failed: no oplog file to replay; make sure you run mongodump with --oplog
2020-08-14T10:44:45.120+0800 0 document(s) restored successfully. 0 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]# ls
oplog.bson

最后执行oplog增量恢复即可

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

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

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

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 1, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 2, "name" : "b" }
{ "_id" : ObjectId("5f35f57409eccc387e65cd8a"), "id" : 3, "name" : "c" }
rstest:PRIMARY>
rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd88"), "id" : 11, "name" : "aa" }
{ "_id" : ObjectId("5f35f4ee09eccc387e65cd89"), "id" : 22, "name" : "bb" }
{ "_id" : ObjectId("5f35f57509eccc387e65cd8b"), "id" : 33, "name" : "cc" }
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)恢复过程

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

use db3
db.db3test.insert({id:111,name:'aaa'})
db.db3test.insert({id:222,name:'bbb'})
db.db3test.insert({id:333,name:'ccc'})

STEP2:执行完整备份

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

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

use db3
db.db3test.insert({id:444,name:'ddd'})
db.db3test.insert({id:555,name:'eee'})
db.db3test.insert({id:666,name:'fff'})

最终数据如下:

rstest:PRIMARY> db.db3test.find()
{ "_id" : ObjectId("5f35fff809eccc387e65cd8c"), "id" : 111, "name" : "aaa" }
{ "_id" : ObjectId("5f35fff809eccc387e65cd8d"), "id" : 222, "name" : "bbb" }
{ "_id" : ObjectId("5f35fff909eccc387e65cd8e"), "id" : 333, "name" : "ccc" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd8f"), "id" : 444, "name" : "ddd" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd90"), "id" : 555, "name" : "eee" }
{ "_id" : ObjectId("5f3600b409eccc387e65cd91"), "id" : 666, "name" : "fff" }
rstest:PRIMARY>

STEP4:模拟数据误操作

rstest:PRIMARY> db
db3
rstest:PRIMARY>
rstest:PRIMARY>
rstest:PRIMARY> db.dropDatabase()
{
"dropped" : "db3",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1597374734, 2),
"signature" : {
"hash" : BinData(0,"0uoicASFK0ppoNhIEuURwElt7Qk="),
"keyId" : NumberLong("6859599294731649027")
}
},
"operationTime" : Timestamp(1597374734, 2)
}
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数据已经恢复到了全备时的状态

rstest:PRIMARY> show dbs
admin 0.000GB
config 0.000GB
db1 0.000GB
db2 0.000GB
db3 0.000GB
lijiamandb 0.000GB
local 0.002GB
maxiangqian 0.000GB
rstest:PRIMARY>
rstest:PRIMARY> use db3
switched to db db3
rstest:PRIMARY> show collections
db3test
rstest:PRIMARY> db.db3test.find()
{ "_id" : ObjectId("5f35fff809eccc387e65cd8c"), "id" : 111, "name" : "aaa" }
{ "_id" : ObjectId("5f35fff809eccc387e65cd8d"), "id" : 222, "name" : "bbb" }
{ "_id" : ObjectId("5f35fff909eccc387e65cd8e"), "id" : 333, "name" : "ccc" }

STEP7:使用oplog恢复到drop操作之前

先确认drop db3数据库的时间点:Timestamp(1597374734, 2)

use local
db.oplog.rs.find(
{
$and : [
{"ns" : {"$regex":"db3"}},
{"op" : "c"},
{"o" : {"dropDatabase":1}}
]
}
).sort({ts:1})

结果如下

/* 1 */
{
"ts" : Timestamp(1597374734, 2),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "c",
"ns" : "db3.$cmd",
"wall" : ISODate("2020-08-14T03:12:14.206Z"),
"o" : {
"dropDatabase" : 1
}
}

执行增量恢复:

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

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

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

rstest:PRIMARY> db.db3test.find()
{ "_id" : ObjectId("5f35fff809eccc387e65cd8c"), "id" : 111, "name" : "aaa" }
{ "_id" : ObjectId("5f35fff809eccc387e65cd8d"), "id" : 222, "name" : "bbb" }
{ "_id" : ObjectId("5f35fff909eccc387e65cd8e"), "id" : 333, "name" : "ccc" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd8f"), "id" : 444, "name" : "ddd" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd90"), "id" : 555, "name" : "eee" }
{ "_id" : ObjectId("5f3600b409eccc387e65cd91"), "id" : 666, "name" : "fff" }

(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)恢复过程

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

use db4
db.db4test.insert({id:1111,name:'aaaa'})
db.db4test.insert({id:2222,name:'bbbb'})
db.db4test.insert({id:3333,name:'cccc'})

STEP2:执行完整备份

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

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

use db4
db.db4test.insert({id:4444,name:'dddd'})
db.db4test.insert({id:5555,name:'eeee'})
db.db4test.insert({id:6666,name:'ffff'})

最终数据如下:

rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd96"), "id" : 5555, "name" : "eeee" }
{ "_id" : ObjectId("5f3628c909eccc387e65cd97"), "id" : 6666, "name" : "ffff" }
rstest:PRIMARY>

STEP4:模拟数据误操作,删除2条数据

rstest:PRIMARY> db.db4test.remove({id:{$gt:4444}})
WriteResult({ "nRemoved" : 2 }) rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }

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

use db4
db.db4test.insert({id:7777,name:'gggg'})
db.db4test.insert({id:8888,name:'hhhh'})
db.db4test.insert({id:9999,name:'kkkk'})

最终数据如下:

rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd98"), "id" : 7777, "name" : "gggg" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd99"), "id" : 8888, "name" : "hhhh" }
{ "_id" : ObjectId("5f3639a109eccc387e65cd9a"), "id" : 9999, "name" : "kkkk" }

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

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

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

STEP7:对该集合执行完全恢复操作

mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 -d db4 -c db4test  /root/backup/full/db4/db4test.bson

STEP8:使用oplog,对该集合执行增量恢复操作

先查看对db4.db4test集合执行删除的开始时间Timestamp(1597389188, 1)

use local
db.oplog.rs.find(
{
$and : [
{"ns" : /db4.db4test/},
{"op" : "d" }
]
}
).sort({ts:1}) /* 1 */
{
"ts" : Timestamp(1597389188, 1),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "d",
"ns" : "db4.db4test",
"ui" : UUID("75507280-3f74-4c17-a3f7-46ce7087c08a"),
"wall" : ISODate("2020-08-14T07:13:08.162Z"),
"o" : {
"_id" : ObjectId("5f3628c809eccc387e65cd96")
}
}
/* 2 */
{
"ts" : Timestamp(1597389188, 2),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "d",
"ns" : "db4.db4test",
"ui" : UUID("75507280-3f74-4c17-a3f7-46ce7087c08a"),
"wall" : ISODate("2020-08-14T07:13:08.162Z"),
"o" : {
"_id" : ObjectId("5f3628c909eccc387e65cd97")
}
}

执行增量恢复:

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

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

rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd98"), "id" : 7777, "name" : "gggg" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd99"), "id" : 8888, "name" : "hhhh" }
{ "_id" : ObjectId("5f3639a109eccc387e65cd9a"), "id" : 9999, "name" : "kkkk" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd96"), "id" : 5555, "name" : "eeee" }
{ "_id" : ObjectId("5f3628c909eccc387e65cd97"), "id" : 6666, "name" : "ffff" }

【完】

2.MongoDB 4.2副本集环境基于时间点的恢复的更多相关文章

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

    (一)MongoDB恢复概述 对于任何类型的数据库,如果要将数据库恢复到过去的任意时间点,否需要有过去某个时间点的全备+全备之后的重做日志,MongoDB也不例外.使用全备将数据库恢复到固定时刻,然后 ...

  2. Mongodb主从复制 及 副本集+分片集群梳理

    转载努力哥原文,原文连接https://www.cnblogs.com/nulige/p/7613721.html 介绍了Mongodb的安装使用,在 MongoDB 中,有两种数据冗余方式,一种 是 ...

  3. 【六】MongoDB管理之副本集

    一.复制介绍 所谓的复制就是在多个主机之间同步数据的过程. 1.数据冗余及可用性 复制技术提供数据冗余及可用性,在不同的数据库服务器上使用多个数据副本,复制技术防止单个数据库服务器出现数据故障而出现数 ...

  4. mongodb系列之---副本集配置与说明

    在配置副本集之前,我们先来了解一些关于副本集的知识. 1,副本集的原理 副本集的原理与主从很相似,唯一不同的是,在主节点出现故障的时候,主从配置的从服务器不会自动的变为主服务器,而是要通过手动修改配置 ...

  5. MongoDB 复制(副本集)学习

    MongoDB 复制(副本集)学习 replication set复制集,复制集,多台服务器维护相同的数据副本,提高服务器的可用性.MongoDB复制是将数据同步在多个服务器的过程.复制提供了数据的冗 ...

  6. 表空间基于时间点的恢复(TSPITR)

    环境:RHEL 6.4 + Oracle 11.2.0.4 准备模拟环境 1. 验证表空间的依赖性 2. 确定执行TSPITR后会丢失的对象 3. 自动执行TSPITR Reference 准备模拟环 ...

  7. Oracle之表空间基于时间点的恢复

    记一次优化过程中:一次误操作,在不影响其他表空间的情况下:采用表空间基于时间点的恢复(TSPITR)方法恢复数据的过程. 1.TSPITR恢复原理    TSPITR目前最方便的方法是使用RMAN进行 ...

  8. MongoDB副本集replica set (二)--副本集环境搭建

    (一)主机信息 操作系统版本:centos7 64-bit 数据库版本   :MongoDB 4.2 社区版 ip hostname 192.168.10.41 mongoserver1 192.16 ...

  9. Mongodb 笔记06 副本集的组成、从应用程序连接副本集、管理

    副本集的组成 1. 同步:MongoDB的复制功能是使用操作日志oplog实现的,操作日志包含了主节点的每一次写操作.oplog是主节点的local数据库中的一个固定集合.备份节点通过查询整个集合就可 ...

随机推荐

  1. web自动化 -- HTMLreport(一)测试报告自定义测试用例名,重写ddt

    一.需求痛点 1.HTMLreport测试报告的用例名不明确 2.希望可以自定义HTMLreport测试报告的用例名 3.痛点截图 二.解决办法 1.原因分析 HTMLreport测试报告中的用例名是 ...

  2. jsp课堂笔记4 javabean

    Javabean是一个可重复使用的软件组件,实际上是一种java类 实现代码重复利用 易编写易维护易使用 jsp页面的主要任务是显示页面,不负责数据的逻辑业务处理 将数据处理过程中指派一个或多个bea ...

  3. css中的名词

    用到的单词 current 当前 hover 悬停 selected 挑选 disabled 禁用 focus 得到焦点 blur 失去焦点 checked 勾选 success 成功 error 出 ...

  4. CMD运行JAVA出现“错误:编码GBK的不可映射字符”

    问题: 原因: 字符编码问题.由于java文件中有中文字符,而cmd在编译时解码默认使用GBK,所以导致无法解码出正确的中文字符. 解决办法: 使用-encoding指令指定运行编码为UTF-8.

  5. 关于RecyclerView(一)基本使用

    前言 最近在项目中用到了ListView,不知道为什么总是出现数据错乱的情况,另外RecyclerView包含很多Item动画,所以改成了RecyclerView. 简单使用 RecyclerView ...

  6. springboot整合邮件发送(163邮箱发送为例)

    先登录163邮箱获取授权  勾选后安装提示会叫你设置授权密码之类的:记住授权的密码 1.引入maven依赖 <dependency> <groupId>org.springfr ...

  7. TCP 服务器端

    """ 建立tcp服务器 绑定本地服务器信息(ip地址,端口号) 进行监听 获取监听数据(监听到的客户端和地址) 使用监听到的客户端client_socket获取数据 输 ...

  8. PHP curl_multi_remove_handle函数

    (PHP 5) curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源 说明 int curl_multi_remove_handle ( resource ...

  9. Ubuntu安装Cloudera Manager以及CDH5.15.2

    一.机子分配 注意,本安装教程是在真机上进行,而非虚拟机.另,此次搭建主要的目的是搭建测试环境,让Hadoop各组件能够运作起来即可,完成搭建后,将用小数据量进行相关数据的计算与测试.线上环境将会使用 ...

  10. P4221 [WC2018]州区划分 无向图欧拉回路 FST FWT

    LINK:州区划分 把题目中四个条件进行规约 容易想到不合法当前仅当当前状态是一个无向图欧拉回路. 充要条件有两个 联通 每个点度数为偶数. 预处理出所有状态. 然后设\(f_i\)表示组成情况为i的 ...