MongoDB之备份与还原

1.  逻辑备份

    1.  完整备份

mongodump(产生json和bson文件)
-h:哪个主机
-u:用户名
-p:密码
-d:数据库名称
-c:集合名称
-o:输出目录
--authenticationDatabase admin  认证库  

    2.  实例

        1.  开启认证的整库备份

            mongodump -h 172.16.20.149:27017 -d test -u root -p Cmr2017 --authenticationDatabase admin -o /home/

        2.  未开启认证的整库备份

            sudo mongodump -h 192.168.1.12:16535 -d zhenpin -o /home/zhenpin

        3.  备份某个collection

            mongodump -h 192.168.1.12:16535 -d zhenpin -c test -o /home/zhenpin/test                                                      

2.  逻辑还原

    1.  完整还原

mongorestore
-h:主机
-u:
-p
--authenticationDatabase
-d
-c
--drop:还原之前删除原来的集合
去掉--drop  恢复数据库时与原数据库合并     

    2.  实例

        /usr/local/mongodb/bin/mongorestore -h 192.168.2.50:16535 -d zhenpin /home/zhangshaohua1510/zhenpin --drop        

3.  数据导出

    1.  mongoexport

mongoexport(必须指定一个集合,目标是一个)
                        -h:指明数据库宿主机的IP
                        -u:指明数据库的用户名
                        -p:指明数据库的密码
                        -d:指明数据库的名字
                        -c:指明collection的名字
                        -f:指明要导出那些列
                        -o:指明到要导出的文件名
                        -q:指明导出数据的过滤条件

    2.  实例

        导出必须指定一个collection,不能导出整个库

        1.  导出json格式

            ./mongoexport -h 192.168.1.125:16535 -d zhenpin -c sensorsdata -o /home/zhangshaohua1510/sensorsdata.dat            

        2.  导出CSV格式

            ./mongoexport -h 192.168.1.125:16535 -d zhenpin -c sensorsdata --csv -f id,name -o  /home/zhangshaohua1510/sensorsdata.csv                                                               

4.  数据导入

    1.  mongoimport

mongoimport
                -type 指明要导入的文件格式
                -headerline 指明不导入第一行
                -file 指明要导入的文件路径
                参数说明:
                        -h:指明数据库宿主机的IP
                        -u:指明数据库的用户名
                        -p:指明数据库的密码
                        -d:指明数据库的名字
                        -c:指明collection的名字
                        -f:指明要导入那些列
          --upsert  更新现有数据,如果不使用--upsert,则导入时已经存在的文档会报_id重复,数据不再插入
          --drop  删除旧数据

    2.  实例

        ./mongoimport -h 192.168.1.125:16535 -d zhenpin -c sensorsdata /home/zhangshaohua1510/sensorsdata.dat

        ./mongoimport -h 192.168.1.125:16535 -d zhenpin -c sensorsdata --type=csv  /home/zhangshaohua1510/sensorsdata.csv

5.  mongoexport/mongoimport与mongodump/mongorestore的对比

    1. mongoexport/mongoimport导入/导出的是JSON格式,而mongodump/mongorestore导入/导出的是BSON格式。

    2. JSON可读性强但体积较大,BSON则是二进制文件,体积小但对人类几乎没有可读性。

    3. 在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump/mongorestore可能不会成功,具体要看版本之间的兼容性。当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport/mongoimport是一个可选项。跨版本的mongodump/mongorestore并不推荐,实在要做请先检查文档看两个版本是否兼容(大部分时候是的)。

    4. JSON虽然具有较好的跨版本通用性,但其只保留了数据部分,不保留索引,账户等其他基础信息。使用时应该注意。 

6.  mongodb的增量备份和还原

    1.  原理

        mongodump中有一个参数--oplog,该参数的主要作用是在导出库集合数据的同时生成一个oplog.bson文件,里面存放了开始进行dump和dump结束之间的所有oplog操作

        

        注意:--oplog选项只对全库导出有效

        仔细观察oplogReplay参数下的还原过程,我们发现,是先还原数据库文件,再重放还原oplog.bson种的数据。这就启发了我们,如果还原路径下,只有oplog.bson文件,没有数据库备份文件,是不是只进行重放还原操作。如此,如果oplog.bson中记录都是上次备份后的变化操作(oplog),还原oplog.bson就可以实现了增量还原。考虑到副本集的变化操作(op log)保存在oplog.rs集合中,只要连续从oplog.rs导出操作的相关数据进行备份,就可以实现增量备份。                

    2.  mongodb完整备份+增量备份

        1.  完整备份

#!/bin/bash
sourcepath='/data/mongodb/mongobin344/bin'
targetpath='/data/mongodb_back/bkXXX_2XXXX'
nowtime=$(date "+%Y%m%d")
start()
{
${sourcepath}/mongodump --host 172.XXX.XXX.XXX --port 2XXXX -u 用户名-p "密码" --oplog --gzip --authenticationDatabase "admin" --out ${targetpath}/${nowtime}
}
execute()
{

echo "================================ $(date) bakXXX 2XXXX mongodb back start  ${nowtime}========="

start
if [ $? -eq 0 ]
then
echo "The MongoDB BackUp Successfully!"
else "The MongoDB BackUp Failure"
fi
}
if [ ! -d "${targetpath}/${nowtime}/" ]
then
  mkdir ${targetpath}/${nowtime}
fi
execute

baktime=$(date -d '-3 days' "+%Y%m%d")
if [ -d "${targetpath}/${baktime}/" ]
then
  rm -rf "${targetpath}/${baktime}/"
  echo "=======${targetpath}/${baktime}/===删除完毕=="
fi

echo "================================ $(date) bakXXX 2XXXX mongodb back end ${nowtime}========="

        2.  增量备份

#!/bin/bash

#### 请在此处输入关键参数,例如程序路径,账号,密码,实例端口###
command_linebin="/data/mongodb/mongobin344/bin/mongo"
username="用户名"
password="用户命名"
port="mongo都被的端口号"
####
####comments0 start 第一次运行此脚本时,自动检查创建备份路径 ####
if [ ! -d "/data/mongodb_back/mongodboplog_back/mongo$port" ]
then
  mkdir -p /data/mongodb_back/mongodboplog_back/mongo$port
fi

if [ ! -d "/data/mongodb_back/mongodboplog_back/log/$port" ]
then
  mkdir -p /data/mongodb_back/mongodboplog_back/log/$port
fi

bkdatapath=/data/mongodb_back/mongodboplog_back/mongo$port
bklogpath=/data/mongodb_back/mongodboplog_back/log/$port

####comments end ##

logfilename=$(date -d today +"%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

bkfilename=$(date -d today +"%Y%m%d%H%M%S")

#### comments1 start 获取数据库中oplog记录的开始范围,防止导出的数据不完整 ####

command_line="${command_linebin} 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" $opmes)

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导出的文档数据量来评估,一个周期内的操作量,和预估如果恢复可能的耗时

##dumpmsg=$(/data/mongodb/mongobin344/bin/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/mongodboplog$bkfilename)
/data/mongodb/mongobin344/bin/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/mongodboplog$bkfilename >> $bklogpath/$logfilename.log 2>&1

#echo "本次导出的具体信息如下:" $dumpmsg
#echo $dumpmsg >> $bklogpath/$logfilename.log

## 调整结束

#### comments2 start  再次检查,防止导出oplog数据过程耗时过长,比如,我们一小时导出一份,每一次循环涵盖65分钟,如果导出执行过程耗时5分钟以上就可能导致导出的数据不完整。####
## 下面的70 是有上面的65+5而得,+5 是允许导出耗时5分钟。这个逻辑有点绕,大家可以测测,这段逻辑看几分钟可以理解通透了。
DiffTime=$(expr 70 \* 60)
AllowMaxDate=$(expr $(date +%s) - $DiffTime)
if [ $AllowMaxDate -le $ParamBakStartDate ]
then
echo "Message --oplog记录导出时间在规定的DiffTime范围内。数据有效" >> $bklogpath/$logfilename.log
else echo "Fatal Error --oplog记录导出时间 超出了 规定的DiffTime范围。数据完整性等不到保证。请增大DiffTime参数或调整备份频率。" >> $bklogpath/$logfilename.log
fi

#### comments2 end ####

#### comments3 检查备份文件是否已经删除start ####
if [ -d "$bkdatapath/mongodboplog$bkfilename" ]
then
  echo "Message --检查此次备份文件已经产生.文件信息为:" $bkdatapath/mongodboplog$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/mongodboplog$keepbaktime ]
then
  rm -rf $bkdatapath/mongodboplog$keepbaktime
  echo "Message -- $bkdatapath/mongodboplog$keepbaktime 删除完毕" >> $bklogpath/$logfilename.log
fi
### comments4 end 


echo "============================Message --MongoDB 端口为" $port "的差异备份结束,结束时间为:" $(date -d today +"%Y%m%d%H%M%S") >> $bklogpath/$logfilename.log       

7.  mongodb完整还原+增量还原

    1.  还原完整备份

        /usr/local/mongodb/bin/mongorestore -h 192.168.2.50 --port 16535 --oplogReplay  --gzip /mongo_backup/2022-11-29-14-42 --drop                

    2.  还原增量备份

        将完整备份所在的目录清空

          rm -rf  /mongo_backup/2022-11-29-14-42/*

        将增量备份的oplog.rs.bson文件复制到完整备份目录下,并修改名称为oplog.bson

        执行还原增量备份的命令

          /usr/local/mongodb/bin/mongorestore -h 192.168.2.50 --port 16535 --oplogReplay  /mongo_backup/2022-11-29-14-42  

        

posted @ 2022-08-08 13:29  奋斗史  阅读(837)  评论(0)    收藏  举报