背景:

  最近后端基于mongo的项目越来越多,MySQL基于冷备份+binlog可以恢复至任意时间点,那么mongo是否有同样的功能呢?经过调研发现可以通过dump+oplog可以实现粒度更细致的恢复。

官方文档关于oplog的说明 : <a class="mongo-link" href="https://docs.mongodb.com/manual/core/replica-set-oplog/"></a>

  以下是实验步骤,附脚本内容。

1、 制作测试数据并且获取冷备

2、模拟线上两个冷备份之间的数据写入

3、备份oplog

4、冷备+oplog恢复至临时实例,确认没问题后,通过临时实例恢复到主库

1、

dump比较重要的几个参数
#mongodump --help
Usage:
mongodump <options> Export the content of a running server into .bson files. Specify a database with -d and a collection with -c to only dump that database or collection. See http://docs.mongodb.org/manual/reference/program/mongodump/ for more information. connection options:
-h, --host=<hostname> mongodb host to connect to (setname/host1,host2 for replica sets)
--port=<port> server port (can also use --host hostname:port) authentication options:
-u, --username=<username> username for authentication
-p, --password=<password> password for authentication
--authenticationDatabase=<database-name> database that holds the user's credentials
--authenticationMechanism=<mechanism> authentication mechanism to use --gzip compress archive our collection output with Gzip
--oplog use oplog for taking a point-in-time snapshot

  

test_1234:PRIMARY> show dbs
admin .000GB
local .724GB
test_1234:PRIMARY> use test
switched to db test
test_1234:PRIMARY> for (var i=;i<=;i++)(db.test.insert({"test":i}))
WriteResult({ "nInserted" : })
test_1234:PRIMARY> db.test.count() 当前test.test有5001条数据,获取冷备份并查看当前时间戳

#date +%s
1553499626


2、 这个时候模拟下冷备之后的数据写入,删除一些数据并记录oplog

test_1234:PRIMARY> use test
switched to db test
test_1234:PRIMARY>
test_1234:PRIMARY>
test_1234:PRIMARY> show tables
test
test_1234:PRIMARY> for (var i=0;i<=5000;i++)(db.after.insert({"after":i}))
WriteResult({ "nInserted" : 1 })
test_1234:PRIMARY> db.test.remove({"test":{$gt:1500}})
WriteResult({ "nRemoved" : 3500 })
test_1234:PRIMARY> db.test.count()
1501
test_1234:PRIMARY> db.after.count()
5001
test_1234:PRIMARY>

#date +%s
1553499686

  

3、备份oplog

./mongoha_dump_oplog.sh 

options:
-S [Start-BSON-Timestamp]
-E [End-BSON-Timestamp]
is running like mongoha_dump_oplog.sh -S -E #

 

./mongoha_dump_oplog.sh -S 1553499626 -E 1553499686
2019-03-25T15:42:07.579+0800 writing local.oplog.rs to
2019-03-25T15:42:10.576+0800 local.oplog.rs 0
2019-03-25T15:42:13.575+0800 local.oplog.rs 0
2019-03-25T15:42:16.575+0800 local.oplog.rs 0
2019-03-25T15:42:19.575+0800 local.oplog.rs 0
2019-03-25T15:42:22.575+0800 local.oplog.rs 0
2019-03-25T15:42:25.576+0800 local.oplog.rs 0
2019-03-25T15:42:26.267+0800 local.oplog.rs 8507
2019-03-25T15:42:26.267+0800 done dumping local.oplog.rs (8507 documents)
Mongo oplog backup [2019-03-25 15:40:26 - 2019-03-25 15:41:26] -->Sucess

  

4、 新建临时实例利用刚才冷备+oplog恢复,确认数据没问题之后,恢复至主库。

1)新建临时端口
mongo_install.sh -T 1 -P 6666 -M 1
2019-03-25 15:32:57 start install
mongodb-linux-x86_64-rhel62-3.4.0/README
mongodb-linux-x86_64-rhel62-3.4.0/THIRD-PARTY-NOTICES
mongodb-linux-x86_64-rhel62-3.4.0/MPL-2
mongodb-linux-x86_64-rhel62-3.4.0/GNU-AGPL-3.0
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongodump
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongorestore
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongoexport
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongoimport
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongostat
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongotop
mongodb-linux-x86_64-rhel62-3.4.0/bin/bsondump
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongofiles
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongooplog
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongoreplay
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongoperf
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongod
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongos
mongodb-linux-x86_64-rhel62-3.4.0/bin/mongo
/usr/local/mongodb is exists ..
mongo data,log dir create sucess 2019-03-25 15:32:57 ----> mongodb6666 start sucess
note: noprealloc may hurt performance in many applications
about to fork child process, waiting until server is ready for connections.
forked process: 8394
child process started successfully, parent exiting 2)恢复冷备+oplog

mongoha_fullrestore.sh

options:
-P specify the port
-p specify the restore db path ,must abspath
is running like mongoha_backup.sh -P 27017 -p /test

mongoha_fullrestore.sh -P 6666 -p /data1/backup/mongodb/2019/03/25/_2019-03-25_15\:15/
at 2019-03-25_15:34 to do restore for mongo
2019-03-25T15:34:48.505+0800 preparing collections to restore from
2019-03-25T15:34:48.506+0800 reading metadata for test.test from /data1/backup/mongodb/2019/03/25/_2019-03-25_15:15/test/test.metadata.json
2019-03-25T15:34:48.544+0800 restoring test.test from /data1/backup/mongodb/2019/03/25/_2019-03-25_15:15/test/test.bson
2019-03-25T15:34:48.573+0800 restoring indexes for collection test.test from metadata
2019-03-25T15:34:48.573+0800 finished restoring test.test (5001 documents)
2019-03-25T15:34:48.573+0800 replaying oplog
2019-03-25T15:34:48.573+0800 done
Mongo restore() -->Sucess

冷备恢复成功

临时节点查看下数据

恢复到冷备之前的数据了,但是之前删除的数据及后插入的after document还未恢复,这时候我们恢复oplog

./mongoha_restore_oplog.sh

options:
-P specify the port
-p specify the restore db path ,must abspath
is running like ./mongoha_restore_oplog.sh -P 临时端口 -p /data1/backup/mongodb/oplog/2019/03/25/local/oplog.rs.bson

再次查看临时库数据

临时库数据以恢复,这时候就可以备份出来恢复至线上了。

附mongoha_fullbackup.sh脚本

 #!/bin/bash
#auth liding@zlongame.com dat=`date "+%Y-%m-%d_%H:%M"`
day=`date "+%Y/%m/%d" -d now`
#localip=`ip a | grep "\binet\b" |awk '{print $2}'| egrep -e "^10|172" | awk -F"/" '{print $1; exit;}'`
basedir="/data1/backup/mongodb/$day" helpfunc(){
echo
echo "options:"
echo " -P specify the port"
echo " is running like mongoha_backup.sh -P 27017 -D test,test1"
} while getopts "P:" Option
do
case $Option in
P) ports=$OPTARG;;
*) helpfunc; exit 1; ;;
esac
done dbname=`echo $dbname | sed 's/,/ /g'`
dobackup(){
echo "at $dat to do bakcup for mongo$i"
mkdir -p "$basedir"
#mongodump -u$bacuser -p$pswd --port $i --oplog -o "$basedir"/mongo"$i"
if /usr/local/mongodb/bin/mongodump -h 127.0.0.1 --port $ports --oplog -o "$basedir"/"$i"_$dat;then
echo "Mongo Backup($i) -->Sucess"
else
echo "Mongo Backup($i) -->faild"
fi } check(){
person=`whoami`
if [ "$person" != "root" ]; then
echo "the user is now $person, checkout to 'root' to continue"
exit 1
fi if [ -z "$ports" ] ;then
helpfunc
exit 1
fi } cleanbackup(){
rmdate=`date "+%Y/%m/%d" -d "7 days ago"`
if [ -d $1 ] ;then
rm -rf $1
echo "rm -$1"
elif [ -d $basedir/$rmdate ] ;then
rm -rf $basedir/$rmdate
echo "rm -rf $basedir/$rmdate"
else
rm -rf $basedir/mongo$1
echo "rm -rf $basedir/mongo$1"
exit 1
fi
}
main(){ check
dobackup
}
main

  

附mongoha_fullrestore.sh脚本

mongoha_fullrestore.sh
#!/bin/bash dat=`date "+%Y-%m-%d_%H:%M"`
day=`date "+%Y/%m/%d" -d now`
#localip=`ip a | grep "\binet\b" |awk '{print $2}'| egrep -e "^10|172" | awk -F"/" '{print $1; exit;}'`
basedir="/data1/backup/mongodb/$day" helpfunc(){
echo
echo "options:"
echo " -P specify the port"
echo " -p specify the restore db path ,must abspath"
echo " is running like mongoha_backup.sh -P 27017 -p $backdir/test"
} while getopts "P:p:" Option
do
case $Option in
P) ports=$OPTARG;;
p) path=$OPTARG;;
*) helpfunc; exit 1; ;;
esac
done #mongorestore -h 127.0.0.1:27017 -d test test/
dorestore(){
echo "at $dat to do restore for mongo${dbname}"
if /usr/local/mongodb/bin/mongorestore --drop --oplogReplay -h 127.0.0.1:${ports} $path;then
echo "Mongo restore(${dbname}) -->Sucess"
else
echo "Mongo restore(${dbname}) -->faild"
fi } check(){
person=`whoami`
if [ "$person" != "root" ]; then
echo "the user is now $person, checkout to 'root' to continue"
exit 1
fi if [ -z "$ports" ] ;then
helpfunc
exit 1
fi } main(){ check
dorestore
}
main

附mongoha_dump_oplog.sh 脚本

cat mongoha_dump_oplog.sh
#!/bin/bash dat=`date "+%Y-%m-%d_%H:%M"`
day=`date "+%Y/%m/%d" -d now` helpfunc(){
echo
echo "options:"
echo " -S [Start-BSON-Timestamp]"
echo " -E [End-BSON-Timestamp] "
echo " is running like mongoha_dump_oplog.sh -S -E "
}
if [ $# -lt 2 ] ;
then
helpfunc
exit 1
else while getopts "S:E:" Option
do
case $Option in
S) start_t=$OPTARG;;
E) stop_t=$OPTARG;;
*) helpfunc; exit 1; ;;
esac
done
fi start_time="Timestamp(${start_t}, 0)"
stop_time="Timestamp(${stop_t}, 0)"
date_now=`date "+%Y%m%d%H_%M" -d now`
backdir="/data1/backup/mongodb/oplog"
#dump
function data_fetch(){
mkdir -p $backdir
query='{ts:{$gt:'$start_time',$lt: '$stop_time' }}'
flags='-d local -c oplog.rs'
if /usr/local/mongodb/bin/mongodump $flags --query "$query" -o $backdir/$date_now;then
echo "Mongo oplog backup [`date -d @${start_t} "+%Y-%m-%d %H:%M:%S"` - `date -d @${stop_t} "+%Y-%m-%d %H:%M:%S"`] -->Sucess"
else
echo "Mongo oplog backup [`date -d @${start_t} "+%Y-%m-%d %H:%M:%S"` - `date -d @${stop_t} "+%Y-%m-%d %H:%M:%S"`] -->Faild"
fi } main(){
data_fetch
}
main

   附mongoha_restore_oplog.sh 脚本

cat mongoha_restore_oplog.sh
#!/bin/bash dat=`date "+%Y-%m-%d_%H:%M"`
day=`date "+%Y/%m/%d" -d now`
#localip=`ip a | grep "\binet\b" |awk '{print $2}'| egrep -e "^10|172" | awk -F"/" '{print $1; exit;}'`
backdir="/data1/backup/mongodb/oplog/$day" helpfunc(){
echo
echo "options:"
echo " -P specify the port"
echo " -p specify the restore db path ,must abspath"
echo " is running like $0 -P 临时端口 -p $backdir/local/oplog.rs.bson"
} if [ $# -lt 2 ] ;
then
helpfunc
exit 1
else
while getopts "P:p:" Option
do
case $Option in
P) port=$OPTARG;;
p) path=$OPTARG;;
*) helpfunc; exit 1; ;;
esac
done
fi function data_restore(){
flags='-d local -c oplog.rs'
if /usr/local/mongodb/bin/mongorestore --port $port $flags $path;then
echo "Mongo restore[$port] -->Sucess"
else
echo "Mongo restore[$port] -->Faild"
fi }
data_restore

  

 

Mongodb基于oplog恢复至任意时间的更多相关文章

  1. 2020-08-01:MySQL 的数据如何恢复到任意时间点?

    福哥答案2020-08-01: 恢复到任意时间点以定时的做全量备份,以及备份增量的 binlog 日志为前提.恢复到任意时间点首先将全量备份恢复之后,再此基础上回放增加的 binlog 直至指定的时间 ...

  2. MongoDB 定位 oplog 必须全表扫描吗?

    MongoDB oplog (类似于 MySQL binlog) 记录数据库的所有修改操作,除了用于主备同步:oplog 还能玩出很多花样,比如 全量备份 + 增量备份所有的 oplog,就能实现 M ...

  3. mysqlbinlog工具基于日志恢复详细解释

    如果每天都会生成大量的二进制日志,这些日志长时间不清理的话,将会对磁盘空间带来很大的浪费,所以定期清理日志是DBA维护mysql的一个重要工作 1)RESET MASTER在上面查看日志存放的文件夹中 ...

  4. 基于FPGA的DDS任意波形发生器设计

    一.简介       DDS技术最初是作为频率合成技术提出的,由于其易于控制,相位连续,输出频率稳定度高,分辨率高, 频率转换速度快等优点,现在被广泛应用于任意波形发生器(AWG).基于DDS技术的任 ...

  5. Python: 处理mongodb文档,怎么让UTC时间转换为本地时间?

    存储数据到MongoDB数据库时,一般我们会加一个更新数据的时间update_time.这时在python代码中 会用到datetime模块以便获取当前系统时间,但是存入到MongoDB数据库时,存储 ...

  6. Python 之 时间字符串、时间戳、时间差、任意时间字符串转换时间对象

    1. 时间字符串 --> 时间戳 1) time 模块 timestring = '2016-12-21 10:22:56' print time.mktime(time.strptime(ti ...

  7. dataguard 归档丢失(主库中无此丢失归档处理),备库基于SCN恢复

    dataguard 归档丢失(主库中无此丢失归档处理),备库基于SCN恢复 环境: OS: CentOS 6.5 DB: Oracle 10.2.0.5 1.主备库环境 主库: SQL> sel ...

  8. C#- 将秒数转化成任意时间格式

    将秒数转化成任意时间格式,可以使用C#的一个函数TimeSpan,看示例: TimeSpan ts = new TimeSpan(0, 0, 3661); richTextBox2.Text = ts ...

  9. mongodb的oplog遇到的问题

    mongodb调整oplog的大小的方法 关闭当前服务器,将服务器以单机模式启动.这是一种方法,还有没有其他方法? mongodb实时扫描oplog,判断记录到哪个地方了 如果扫描oplog的程序挂掉 ...

随机推荐

  1. win7 + python2.7 安装scipy

    问题: 直接pip install scipy将不能正确安装,缺少文件 方法: 下载  "scipy‑0.19.0‑cp27‑cp27m‑win_amd64.whl"[90多M] ...

  2. 打包python文件,让文件程序化

    通过对源文件打包,Python程序可以在没有安装 Python的环境中运行,也可以作为一个独立文件方便传递和管理. 现在网上主流的打包方式有两种py2exe或者pyinstaller两款多平台的Pyt ...

  3. 批量修改文件名的bash脚本

    #!/bin/bash while IFS='' read -r line || [[ -n "$line" ]]; do # echo "sox $line --cha ...

  4. css移除a标签及map、area(图片热区映射)点击过后的边框

    默认a标签及其包含的html元素和map中的area(图片热区映射)在点击过后留有默认的蓝色边框,如下图 可以看到,蓝色的边框破坏了页面的整体美感,很多时候我们都是不需要的.通过设置相应的css可以去 ...

  5. MySQL 存储引擎、锁、调优、失误与事务回滚、与python交互、orm

    1.存储引擎(处理表的处理器) 1.基本操作 1.查看所有存储引擎 mysql> show engines; 2.查看已有表的存储引擎 mysql> show create table 表 ...

  6. 安装git之后,桌面图标出现很多的蓝色问号

    今天在搞git之后,开机发现多了好多的问号: 这是因为我们在桌面创建了版本库了. 这个时候我们在系统中吧隐藏的文件夹显示出来.这个时候会看到桌面上有一个隐藏的git文件夹.把这个文件夹删除掉之后,刷新 ...

  7. PHP环境基础配置

    域名访问设置(本地局域网) 用记事本打开 127.0.0.1是本地回环地址 配置完后 通过在本地浏览器输入www.0705.com就可以访问本地站点了 Wamp集成环境多站点配置 配置条件: 一个服务 ...

  8. 监控服务器所有用户的操作记录(测试只记录root用户)

    在linux系统的环境下,不管是root用户还是其它的用户只有登陆系统后用进入操作我们都可以通过命令history来查看历史记录,可是假如一台服务器多人登陆,一天因为某人误操作了删除了重要的数据.这时 ...

  9. C语言和C++中的字符串(string)

    知识内容: 1.C\C++字符串简述 2.C字符串相关操作 3.C++ string类相关操作 一.C\C++字符串简述 1.C语言字符串 C语言字符串是字符的数组.单字节字符串顺序存放各个字符串,并 ...

  10. 移动app非功能测试点收集

    非功能测试 移动app测试的另一重要方面是移动app的非功能需求.移动app在推出市场或进行进一步开发前,移动测试员有许多需要测试的问题. 早期开发阶段要进行的第一个测试应该是实用性测试.通常是由al ...