1、备份-脚本 mongodb_backup_incremental.sh

!/bin/bash
#### 请在此处输入关键参数,例如程序路径,账号,密码,实例端口###
command_linebin=”/mongodb/mongodb-4.0.10/bin”
username=”xxx”
password=”xxx”
port=”27017”
####
####comments0 start 第一次运行此脚本时,自动检查创建备份路径 ####
if [ ! -d “/mongodb/backup/incremental/mongo-$port” ];then
mkdir -p /mongodb/backup/incremental/mongo-$port
fi

if [ ! -d “/mongodb/backup/incremental/log-$port” ];then
mkdir -p /mongodb/backup/incremental/log-$port
fi

bkdatapath=/mongodb/backup/incremental/mongo-$port
bklogpath=/mongodb/backup/incremental/log-$port
####comments end ##
logfilename=$(date +”%Y%m%d”)
echo “===Message —MongoDB端口为”$port”的差异备份开始,开始时间为:”$(date -d today +”%Y%m%d%H%M%S”) >> $bklogpath/$logfilename.log
ParamBakEndDate=$(date +%s)
echo “Message —本次备份时间参数中的结束时间为:” $ParamBakEndDate >> $bklogpath/$logfilename.log
DiffTime=$(expr 65 * 60)
echo “Message —备份设置的间隔时间为:” $DiffTime >> $bklogpath/$logfilename.log
ParamBakStartDate=$(expr $ParamBakEndDate - $DiffTime)
echo “Message —本次备份时间参数中的开始时间为:” $ParamBakStartDate >> $bklogpath/$logfilename.log
###上文中的DiffTime用来备份前检查oplog中的数据是否满足要求,即最早的一笔数据要满足在 65分钟前,那么备份后应该也要检查一下。
###防止在备份的过程中有大量的操作,将前面的尚未导出的oplog数据覆盖掉。 例如,08:00执行导出,备份前最早的一笔数据要在06:00
###执行完毕后,再次检查oplog中最早的一笔数据,就是要在07:00之前,在此我们要求在06:59即61分钟前。
###再次增加一个时间参数,用来表示备份后,oplog必须满足的时间要求,参数命名为
DiffTime=$(expr 61 * 60)
ParamAfterBakRequestStartDate=$(expr $ParamBakEndDate - $DiffTime)
echo “Message —为保证备份的连续性,本次备份后,oplog中的开始时间需小于:” $ParamAfterBakRequestStartDate >> $bklogpath/$logfilename.log
##### end
bkfilename=$(date -d today +”%Y%m%d%H%M%S”)
### comments1 start 获取数据库中oplog记录的开始范围,防止导出的数据不完整 ###
command_line=”${command_linebin}/mongo localhost:$port/admin -u$username -p$password”
opmes=$(/bin/echo “db.printReplicationInfo()” | $command_line —quiet)
echo $opmes > opdoctime$port.tmplog
opbktmplogfile=opdoctime$port.tmplog
opstartmes=$(grep “oplog first event time” $opbktmplogfile | awk -F ‘CST’ ‘{print $1}’ | awk -F ‘oplog first event time: ‘ ‘{print $2}’ | awk -F ‘ GMT’ ‘{print $1}’)
echo “Message —oplog集合记录的开始时间为:”$opstartmes >> $bklogpath/$logfilename.log
oplogRecordFirst=$(date -d “$opstartmes” +%s)
echo “Message —oplog集合记录的开始时间为[时间格式化]:” $oplogRecordFirst >> $bklogpath/$logfilename.log
##begin 比较备份参数的开始时间是否在oplog记录的时间范围内
if [ $oplogRecordFirst -le $ParamBakStartDate ]
then
echo “Message —检查设置备份时间合理。备份参数的开始时间在oplog记录的时间范围内。” >> $bklogpath/$logfilename.log
else
echo “Fatal Error —检查设置的备份时间不合理合理。备份参数的开始时间不在oplog记录的时间范围内。请调整oplog size或调整备份频率。本次备份可以持续进行,但还原时数据完整性丢失。” >> $bklogpath/$logfilename.log
fi
##end##
### comments1 end ###
## 调整一下命令,将备份的过程打印到log文件中,我们可以从local.oplog.rs导出的文档数据量来评估,一个周期内的操作量,和预估如果恢复可能的耗时
${command_linebin}/mongodump -h localhost —port $port —authenticationDatabase admin -u$username -p$password -d local -c oplog.rs —query ‘{ts:{$gte:Timestamp(‘$ParamBakStartDate’,1),$lte:Timestamp(‘$ParamBakEndDate’,9999)}}’ -o $bkdatapath/$bkfilename >> $bklogpath/$logfilename.log 2>&1
## 调整结束
#### comments2 start 再次检查,防止导出oplog数据过程耗时过长,因oplog是固定集合,如果操作期间有大量的操作,则oplog中新的数据会覆盖掉旧的数据,就可能导致导出的数据不完整,无法保证增量文件间的时间连续性。因此备份后再次检查####
echo $opmes > opdoctime$port.tmplog
opbktmplogfile=opdoctime$port.tmplog
echo “Message —执行备份后,oplog集合记录的开始时间为:”$opstartmes >> $bklogpath/$logfilename.log
oplogRecordFirst=$(date -d “$opstartmes” +%s)
echo “Message —执行备份后,oplog集合记录的开始时间为[时间格式化]:” $oplogRecordFirst >> $bklogpath/$logfilename.log
##begin 比较备份参数的开始时间是否在oplog记录的时间范围内
if [ $oplogRecordFirst -le $ParamAfterBakRequestStartDate ]
then
echo “Message —备份后,检查oplog集合中数据的开始时间,即集合中最早的一笔数据,时间不小于61分钟的时间(即参数 ParamAfterBakRequestStartDate)。这样可以保证每个增量备份含有最近一个小时的全部op操作,满足文件的持续完整性,逐个还原无丢失数据风险。” >> $bklogpath/$logfilename.log
else
echo “Fatal Error —备份后,检查oplog集合的涵盖的时间范围过小(小于61min)。设置的备份时间不合理合理,备份后的文件不能完全涵盖最近60分钟的数据。请调整oplog size或调整备份频率。本次备份可以持续进行,但还原时数据完整性丢失。” >> $bklogpath/$logfilename.log
fi
#### comments2 end ####
#### comments3 检查备份文件是否已经存在start ####
if [ -d “$bkdatapath/$bkfilename” ]
then
echo “Message —检查此次备份文件已经产生.文件信息为:” $bkdatapath/$bkfilename >> $bklogpath/$logfilename.log
else
echo “Fatal Error —备份过程已执行,但是未检测到备份产生的文件,请检查!” >> $bklogpath/$logfilename.log
fi
##### comments3 end ####
#### comments4 start 删除历史备份文件,保留3天,如需调整,请在持续设置
keepbaktime=$(date -d ‘-3 days’ “+%Y%m%d%H”)*
if [ -d $bkdatapath/$keepbaktime ]
then
rm -rf $bkdatapath/$keepbaktime
echo “Message — $bkdatapath/$keepbaktime 删除完毕” >> $bklogpath/$logfilename.log
fi
### comments4 end
echo “===Message —MongoDB端口为”$port”的差异备份结束,结束时间为:” $(date -d today +”%Y%m%d%H%M%S”) >> $bklogpath/$logfilename.log

===========================================================================================================

2、恢复-脚本 mongodb_restore_incremental.sh

!/bin/bash
echo -e “\033[31;1m*[ Mongodb ] 增量恢复脚本*\033[0m”
#### 请在此处输入关键参数,例如程序路径,账号,密码,实例端口###
command_linebin=”/mongodb/mongodb-4.0.10/bin”
username=”xxx”
password=”xxx”
port=”27017”
bkdatapath=/mongodb/backup/incremental/mongo-$port
tempPath=/mongodb/backup/incremental/tmp
####
echo -e “\033[32;1m[ 选择要恢复增量的日期(格式:年月日时分秒) ] \033[0m”
for backfile in ls $bkdatapath; do
echo $backfile
done
read -p “>>>” date_bak
if [[ $date_bak == “” ]] || [[ $date_bak == ‘.’ ]] || [[ $date_bak == ‘..’ ]]; then
echo -e “\033[31;1m输入不能为特殊字符.\033[0m”
exit 1
fi
if [ -d $bkdatapath/$date_bak ]; then
read -p “请确认是否恢复[$date_bak]增量备份[y/n]:” choice
if [ “$choice” == “y” ]; then
echo -e “\033[32;1m正在进行[$date_bak]增量恢复,请稍后…\033[0m”
mkdir -p $tempPath && cp -a $bkdatapath/$date_bak/local/oplog.rs.bson $tempPath/oplog.bson
$command_linebin/mongorestore -h localhost —port $port -u$username -p$password —authenticationDatabase “admin” —oplogReplay $tempPath
rm -rf $tempPath
if [ $? -eq 0 ]; then
echo -e “\033[32;1m————[$date_bak]增量恢复成功————\033[0m”
else
echo -e “\033[31;1m恢复失败,请手动检查!\033[0m”
exit 3
fi
else
exit 2
fi
else
echo “\033[31;1m输入信息错误.\033[0m”
exit 1
fi