MongoDB数据库基于时间点恢复数据

恢复的大概思路和mysql数据库相似,先恢复基础备份,再用日志做增量恢复,最后达到基于时间点恢复的目的。

##一、实验环境:
centos 7
MongoDB 4.0

两个实例,生产实例端口号27017,临时实例端口号27018。

执行这三个命令,建立目录:
mkdir /root/mtmp ---临时实例27018的数据目录
mkdir /tmp/bak ---生产环境的备份目录
mkdir /tmp/zl ---保存基础备份至误操作期间的oplog

##二、实验步骤:
###1、做基础备份
mongodump -u root -p 123456 --authenticationDatabase=admin --oplog -o /tmp/bak

###2、向ceshi.t1集合插入一些测试数据,然后将t1集合删掉。

MongoDB Enterprise rschai:PRIMARY> db.t1.insert({id:1})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise rschai:PRIMARY> db.t1.insert({id:2})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise rschai:PRIMARY> db.t1.insert({id:3})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise rschai:PRIMARY> db.t1.drop()

###3、开始恢复操作
####3.1 查看备份的生成时间
stat /tmp/bak/oplog.bson执行这个命令可以查看到备份文件的创建时间,
【2019-12-08 16:30:46】,转换成时间戳【1575793846】,要记住这个时间戳。

[root@centos bak]# stat /tmp/bak/oplog.bson
File: ‘/tmp/bak/oplog.bson’
Size: 220 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 1179703 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2019-12-08 16:30:46.732281976 +0800
Modify: 2019-12-08 16:30:46.810281965 +0800
Change: 2019-12-08 16:30:46.810281965 +0800
Birth: -

####3.2 找到删除命令的时间
执行这个查询,可以找到ceshi执行过的command命令记录。
db.getCollection('oplog.rs').find({ns:"ceshi.$cmd"})
如果是remove的,可以这样找下
\---------------------------------------------------------------
db.getCollection('oplog.rs').find({op:"d",ns:"ceshi.t1",ts:{$gt:Timestamp(1575796500,1)}})

op:"d" ---代表remove操作
ns:"ceshi.t1" ----对ceshi库t1表做的操作。
ts:{$gt:Timestamp(1575796500,1)} ---修改时间,$gt是大于这个时间戳的操作。
\---------------------------------------------------------------

[root@centos bak]# db.getCollection('oplog.rs').find({ns:"ceshi.$cmd"})
显示的内容很多,最终找到误操作的时间点。
/* 13 */
{
"ts" : Timestamp(1575793969, 1),
"t" : NumberLong(9),
"h" : NumberLong(-8371824852405956941),
"v" : 2,
"op" : "c",
"ns" : "ceshi.$cmd",
"ui" : UUID("29f72724-baae-4f7f-84cb-4c044b84a45f"),
"wall" : ISODate("2019-12-08T16:32:49.930+08:00"),
"o" : {
"drop" : "t1"
}
}


可以看到"ts" : Timestamp(1575793969, 1) 做的删除操作,记住这个时间戳。

####3.3增量日志
找到备份时间点和删除时间点的Oplog日志,备份成bson文件,最后要用这个bson文件做增量恢复。
基础备份时间点:1575793846
误操作时间点:1575793969

mongodump -uroot -p123456 --authenticationDatabase=admin -d local -c oplog.rs -q '{ts:{$lt:Timestamp(1575793969, 1),$gt: Timestamp(1575793846, 1)}}' -o /tmp/zl

可能有人怀疑备份时间是毫秒级的【16:30:46.732281976】,我找的Oplog日志是秒级的【16:30:46】,中间的这0.7秒日志写入到临时实例中会有重复数据,其实不会的,mongo的Oplog日志具有幂等性,执行一次和执行n次,效果是一样的。

####3.4恢复到临时实例
启动一个新实例,端口号设置为27018
mongod --dbpath=/root/mtmp --logpath=/root/mtmp/27018.log --port=27018 --bind_ip_all
导入基础备份数据
mongorestore --port 27018 --oplogReplay /tmp/bak

[root@centos ~]# mongorestore --port 27018 --oplogReplay /tmp/bak
2019-12-08T16:45:54.797+0800 preparing collections to restore from
2019-12-08T16:45:54.801+0800 reading metadata for chai.t1 from /tmp/bak/chai/t1.metadata.json
2019-12-08T16:45:54.801+0800 reading metadata for chai.t2 from /tmp/bak/chai/t2.metadata.json
2019-12-08T16:45:54.825+0800 restoring chai.t1 from /tmp/bak/chai/t1.bson
2019-12-08T16:45:54.858+0800 restoring chai.t2 from /tmp/bak/chai/t2.bson
2019-12-08T16:45:54.883+0800 no indexes to restore
2019-12-08T16:45:54.884+0800 finished restoring chai.t2 (2 documents)
2019-12-08T16:45:57.794+0800 [#########...............] chai.t1 193MB/475MB (40.7%)
2019-12-08T16:46:00.799+0800 [#######################.] chai.t1 471MB/475MB (99.2%)
2019-12-08T16:46:00.828+0800 [########################] chai.t1 475MB/475MB (100.0%)
2019-12-08T16:46:00.828+0800 no indexes to restore
2019-12-08T16:46:00.828+0800 finished restoring chai.t1 (297023 documents)
2019-12-08T16:46:00.828+0800 restoring users from /tmp/bak/admin/system.users.bson
2019-12-08T16:46:00.962+0800 replaying oplog
2019-12-08T16:46:00.963+0800 done

导入增量数据
mongorestore --port 27018 --oplogReplay /tmp/zl/local/oplog.rs.bson

[root@centos ~]# mongorestore --port 27018 --oplogReplay /tmp/zl/local/oplog.rs.bson
2019-12-08T16:46:55.159+0800 checking for collection data in /tmp/zl/local/oplog.rs.bson
2019-12-08T16:46:55.159+0800 replaying oplog
2019-12-08T16:46:55.196+0800 done

###4、登录新实例
登录新实例后,可以看到误操作之前的数据。
[root@centos ~]# mongo --port 27018
MongoDB Enterprise > use ceshi
switched to db ceshi
MongoDB Enterprise > show tables
t1
MongoDB Enterprise > db.t1.find()
{ "_id" : ObjectId("5decb52806d5524f6e0ee91e"), "id" : 1 }
{ "_id" : ObjectId("5decb52a06d5524f6e0ee91f"), "id" : 2 }
{ "_id" : ObjectId("5decb52b06d5524f6e0ee920"), "id" : 3 }
MongoDB Enterprise >

原文地址:https://www.cnblogs.com/nanxiang/p/14058972.html