瞧一瞧!這兒實現了MongoDB的增量備份與還原(含部署代碼)

一 需求描述

咱們知道數據是公司的重要資產,業務的系統化、信息化就是數字化。數據高效的存儲與查詢是系統完善和優化的方向,而數據庫的穩定性、可靠性是實現的基礎。高可用和RPO(RecoveryPointObjective,復原點目標,指能容忍的最大數據丟失量)是衡量一個數據庫優劣的重要指標。做爲一個DBA,搭建數據庫可靠性體系時,必定會要考慮對數據庫進行容災備份。例如,SQL Server類型的數據庫,咱們必定會部署做業,按期進行完整備份、差別備份和日誌備份;MySQL 數據庫一樣如此,也是按期進行完整備份、binlog備份等。html

可能不少公司的DBA認爲本身的數據庫已採用了新的高可用方案,是多結點冗餘了,再也不須要冗餘備份了,例如SQL Server 的AlwaysOn,MySQL的MHA。但是,咱們仍是要強調兩點。mongodb

1.墨菲定律:若是有兩種或兩種以上的方式去作某件事情,而其中一種選擇方式將致使災難,則一定有人會作出這種選擇。shell

過往無數的慘痛教訓說明,將損失放大的緣由就是備份數據也損壞了(你們不重視,實際上極可能就沒作)。數據庫

2.容災備份不只僅能夠解決物理故障,還能夠將一些其它誤操做回滾,將數據的損害降至最低。bash

數據容災備份是爲數據的災難恢復加固了最後一道保障牆。app

國務院信息化工做辦公室領導編制的《重要信息系統災難恢復指南》也對災難恢復能力等級作了詳細劃分。ide

 

     災難恢復能力等級性能

RTO測試

                     RPO大數據

1

2天以上

1天至7天

2

24小時之後

1天至7天

3

12小時以上

數小時至1天

4

數小時至2天

數小時至1天

5

數分鐘至2天

0至30分鐘

6

數分鐘

0

 

隨着MongoDB使用的愈來愈普及,存儲的數據愈來愈重要,對其進行按期備份頗有必要。如今業內廣泛流行的作法是天天定時進行一次全庫備份,出故障時,進行全庫還原。可是一天一次的備份,很難保證恢復後的數據時效性,RPO較差,會有幾個小時的數據丟失。例如,天天5點進行完整備份,若是故障點是晚上20:00,那麼就會丟失15個小時的數據。對比上面的「災難恢復能力等級「」列表,會發現,咱們的災難能力等級比較低。

若是每小時作一次所有備份,那麼對存儲空間的要求較高,還有就是對性能也會有影響。因此,探究Mongodb的增量備還與原頗有必要!!!

二 原理說明

關係型數據庫,例如MySQL ,SQL Server 都有事務日誌(或bin log),會將數據庫的DML 、DDL、DCL等操做記錄在事務文件中,能夠經過日誌備份來搭建增量容災還原體系。MongoDB沒有此類機制和數據文件,難以實現。可是MongoDB副本集有經過oplog(位於local數據庫oplog.rs集合中) 實現節點間的同步,此集合記錄了整個mongod實例在一段時間內的全部變動(插入/更新/刪除)操做。基於此,是否能夠考慮經過oplog.rs集合的備份還原來實現實例的增量備份與增量還原。

查看mongodb備份命令Mongodump,其中有一個相關參數oplog。

Mongodump --oplog參數

參數

參數說明

--oplog

Use oplog for taking a point-in-time snapshot

 

該參數的主要做用是在導出庫集合數據的同時生成一個oplog.bson文件,裏面存放了開始進行dump到dump結束之間全部的op log 操做。

 

注意:--oplog選項只對全庫導出有效。

相應的 Mongorestore 中與 Oplog 相關的參數

參數

參數說明

oplogReplay

replay oplog for point-in-time restore

oplogLimit

only include oplog entries before the provided Timestamp

oplogFile

oplog file to use for replay of oplog

 

 

 仔細觀察oplogReplay參數下的還原過程,咱們發現,是先還原數據庫文件,再重放還原oplog.bson種的數據。這就啓發了咱們,若是還原路徑下,只有oplog.bson文件,沒有數據庫備份文件,是否是隻進行重放還原操做。如此,若是oplog.bson中記錄都是上次備份後的變化操做(op log),還原oplog.bson就能夠實現了增量還原。考慮到副本集的變化操做(op log)保存在oplog.rs集合中,只要連續從oplog.rs導出操做的相關數據進行備份,就能夠實現增量備份。

即理論上,從oplog.rs導出的數據徹底能夠替代mongodump過程當中產生的oplog.bson,進行增量還原。

實際生產中通過屢次驗證,也是徹底能夠。

-----具體原理及驗證內容還可參考本人博客 --https://www.cnblogs.com/xuliuzai/p/9832333.html

三 代碼實現【重點推薦

在容災體系建設中,既有全庫的完整備份也有增量備份。下面是咱們的實現代碼,由於MongoDB可能是在Linux系統下部署,因此這些備份代碼都是經過shell語言實現。這些代碼你們只要稍微改動,調整部分參數,便可部署應用。

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}========="

 

代碼說明:

1.完整備份的腳本,經過crontab觸發執行,天天執行一次。

2.備份完整後,會將三天前的備份文件自動刪除。

3.sourcepath 定義了MongoDB 運行程序所在路徑;targetpath定義了歸檔文件存放的文件夾(請提早建立)。

 

2. 實現增量備份的代碼

 

#
# This file is used by cron to Backup the data of oplog collection,the collection is part of local DB.
# The oplog (operations log) is a special capped collection that keeps a rolling record of all operations 
# that modify the data stored in your databases.All replica set members contain a copy of the oplog, 
# in the local.oplog.rs collection, which allows them to maintain the current state of the database.
# Each operation in the oplog is idempotent. That is, oplog operations produce the same results 
# whether applied once or multiple times to the target dataset.
#
# We backup the collections by periodicity to restore the DB  in case of  DB disaster 
# The version is defined V.001
# Version   ModifyTime                ModifyBy              Desc
# Ver001    2018-11-06 17:00         xuchangpei             Create the Scripts File
#
#
#!/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

 

代碼說明:

1.增量備份的腳本,也是經過crontab觸發執行,以上參數未修改前,建議每小時執行一次。

2.備份完整後,會自動檢查文件是否產生,而且會將三天前的備份文件刪除。

3.腳本會自動檢查備份路徑,不存在將自動產生。

4.增量導出中開始時間和結束時間是最重要的參數,而且要對參數的合法性、有效性檢查。例如,檢查Oplog的記錄是否徹底涵蓋輸入的時間,防止出現但願導出08:00--09:00的數據,可是oplog集合中只有08:30--09:00的數據;防止導出過程耗時過長(例如超過定義的5分鐘),致使數據不完整。代碼中都會對這些異常進行判斷和捕獲。

 

 2018-11-30 01:48 再次更新,將代碼調整以下,主要針對 判斷增量備份出的oplog數據可否涵蓋60分鐘。本代碼爲不小於61分鐘,你們可根據需求調整。

 

前面的代碼,是經過限制備份時間(要小於5分鐘)來作判斷的,仔細分析下,oplog是固定集合,大小由oplogsize設置,其覆蓋狀況有插入量的多少來決定,不是時間來決定。若是短期有大量的插入就會很快覆蓋掉前面的操做,即1分鐘的大量操做徹底可能會覆蓋掉前面20分鐘的操做,因此,有可能有這種狀況發生,例如,08:00 執行增量備份,備份時間參數命令爲06:55---08:00,執行到08:02 結束。可是在08:00 -08:01 期間有大量的寫操做,此時oplog中 06:55 --07:10的集合極可能會被新進來的08:00 -08:01覆蓋掉了,因此,備份導出的數據數據07:10 以前的數據頗有多是丟失的,不完整的。最保險的辦法,仍是經過db.printReplicationInfo()檢查判斷。

因此代碼調整以下:

#
# This file is used by cron to Backup the data of oplog collection,the collection is part of local DB.
# The oplog (operations log) is a special capped collection that keeps a rolling record of all operations 
# that modify the data stored in your databases.All replica set members contain a copy of the oplog, 
# in the local.oplog.rs collection, which allows them to maintain the current state of the database.
# Each operation in the oplog is idempotent. That is, oplog operations produce the same results 
# whether applied once or multiple times to the target dataset.
#
# We backup the collections by periodicity to restore the DB  in case of  DB disaster 
# The version is defined V.001
# Version   ModifyTime                ModifyBy              Desc
# Ver001    2018-11-06 17:00         xuchangpei             Create the Scripts File
#
#
#!/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

####上文中的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} 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數據過程耗時過長,因oplog是固定集合,若是操做期間有大量的操做,則oplog中新的數據會覆蓋掉舊的數據,就可能致使導出的數據不完整,沒法保證增量文件間的時間連續性。所以備份後再次檢查####
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 $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/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

(第二份代碼 還沒有大量驗證,由於咱們的oplogsize設置的較大,oplog數據範圍沒有小於60分鐘的風險。部署的可能是前面的第一份代碼。但從準確性上來說,後者要強於前者,待大量驗證完善,將逐漸推廣。)

四 功能測試驗證

1. 測試環境

 

Item ServerIP Port User DB
源庫 172.XXX.XXX.124(Primary) 2XXX30 testoplog
備份還原庫 172.XXX.XXX.124(Primary) 2XXX20

 

2. 完整備份與還原

step 1 在備份前,先向數據庫testoplog插入部分數據

step 2 完整備份全部的數據庫,執行的代碼爲上面的完整備份代碼(保存到執行文件bkoplogtest_2XXX30),打印出執行過程以下截圖

step 3 還原完整備份,執行的代碼和打印執行過程以下:

執行的命令:

/data/mongodb/mongobin344/bin/mongorestore -h 172.XXX.XXX.124 --port 2XXX20  --oplogReplay --authenticationDatabase 認證數據庫-u 用戶名-p '密碼' --gzip /data/mongodb_back/testoplogbackfile/20181107

打印出的執行過程:

step 4 檢查還原庫的狀況,檢查庫(testoplog)、表(testfullbefore0一、testfullbefore0二、testfullbefore03)是否還原。

結論:完整還原後與原庫完整備份時數據一致,符合測試預期。

 

 3. 增量備份與還原

 

增量備份與還原的測試案例描述

 

測試案例 第一次增量備份 第一次增量還原 第二次增量備份 第二次增量還原
源庫

備份前,新建集合testdiffbk01

並插入10000筆數據

 無操做

備份前,新建集合testdiffbk02

並插入10000筆數據

 無操做
還原庫 無操做

還原後,檢查testdiffbk01是否存在

以及數據量

 無操做

還原後,檢查testdiffbk02是否存在

以及數據量

 

step 1 第一次增量備份前,向源庫中插入測試數據

step 2 第一次執行增量備份(執行增量備份的腳本,代碼放置在執行文件mongodb_oplogbacktestoplog2XXXX.sh中)

 

step 3 向源庫中第二次插入測試數據

step 4 第二次執行增量備份

兩次增量備份產生的文件在 文件夾 /data/mongodb_back/mongodboplog_back/mongo27230 中,以下圖所示:

step 5 將完整備份所在路徑下的文件清空,將第一次備份的產生的oplog.rs.bson 文件,copy至此路徑下,並重命名爲oplog.bson。【即還原第一份增量備份

清空指令:

Copy+ 重命名指令

還原指令:

/data/mongodb/mongobin344/bin/mongorestore -h 172.XXX.XXX.124 --port 2XXX20 --oplogReplay --authenticationDatabase 驗證數據庫-u 用戶名-p '密碼' /data/mongodb_back/testoplogbackfile/20181107

 

step 7 驗證第一次增量還原的數據,驗證測試所用的集合testdiffbk01及數據,與原庫第一次增量備份時一致,即已正常還原增量。

step 8 將完整備份所在路徑下的文件清空,將第二次增量備份的產生的oplog.rs.bson 文件,copy至此路徑下,並重命名爲oplog.bson。【即還原第二份增量備份

刪除指令

copy + 重命名指令

還原增量備份的指令【與第一次執行的還原命令徹底同樣】

/data/mongodb/mongobin344/bin/mongorestore -h 172.XXX.XXX.124 --port 2XXX20  --oplogReplay --authenticationDatabase 驗證數據庫-u 用戶名-p '密碼' /data/mongodb_back/testoplogbackfile/20181107

 

step 9  驗證第二次增量還原的數據,驗證測試所用的集合testdiffbk02及數據。結論:與原庫第二次增量備份時一致,即已正常還原增量。

 此輪測試有完整備份與完整還原,還有兩次增量備份月增量,詳細演示增量還原方案的可行性和相關代碼的可執行性,部署後知足生產所需。

五 注意事項

必定要在還原完整備份的路徑下,還原已備份oplog的增量文件。即先將已還原的完整備份文件刪除,再將增量備份產生oplog.rs.bson文件copy至路徑下,而且重命名爲oplog.bson。

若是是在其餘路徑下,則報錯,主要的錯誤信息爲:

2018-11-06T10:24:51.848+0800 checking for collection data in /data/mongodb_back/bkrcs_test/oplog.bson
2018-11-06T10:24:51.848+0800 Failed: no oplog file to replay; make sure you run mongodump with --oplog

驗證測試,完整備份(全庫備份)的文件在 路徑  /XXX/XXXX_back/bkrcs_2XXXX/20181105 下 。

若是咱們將oplog的增量文件(oplog.rs集合導出的數據)/local/oplog.rs.bson 複製至 /XXX/XXXX_back/bkrcs_test/路徑下,並重命名爲oplog.bson

執行restore命令報錯:

若是咱們將/local/oplog.rs.bson複製至還原完整備份所在的路徑下( /XXX/XXXX_back/bkrcs_27XXX/20181105),執行restore,測試再也不報錯。

 

檢查新增數據也已同步過去。

因此,還原時增量備份(oplog)必定要放置完整備份所在的文件夾下(copy前,先將完整備份完結刪除)進行還原。

 

本文版權歸做者全部,未經做者贊成不得轉載,謝謝配合!!!

 本文版權歸做者全部,未經做者贊成不得轉載,謝謝配合!!!

本文版權歸做者全部,未經做者贊成不得轉載,謝謝配合!!!

相關文章
相關標籤/搜索