2.MongoDB 4.2副本集環境基於時間點的恢復

image


(一)MongoDB恢復概述
對於任何數據庫,若是要將數據庫恢復到過去的任意時間點,否須要有過去某個時間點的全備+全備以後的重作日誌。
接下來根據瑞麗航空的狀況進行概述:
全備:天天晚上都會進行備份;
重作日誌備份:MongoDB只有開啓主從複製或者副本集時纔會開啓重作日誌,主從複製存放在local數據庫下的「oplog.$main」集合中,複製集的日誌存放在local數據庫下的oplog.rs集合中,該集合是一個上限集合,當達到固定大小時,最老的記錄會被自動覆蓋。所以須要注意,MongoDB的重作日誌並不會一直保存着,可否恢復到故障點,徹底取決於日誌是否完整。html


(二)基礎環境
本次測試備份恢復使用的是MongoDB 4.2版本副本集環境,副本集配置以下:node

rstest:PRIMARY> rs.config()
 {
     "_id" : "rstest",
     "version" : 2,
     "protocolVersion" : NumberLong(1),
     "writeConcernMajorityJournalDefault" : true,
     "members" : [
         {
             "_id" : 0,
             "host" : "192.168.10.41:27017",
             "arbiterOnly" : false,
             "buildIndexes" : true,
             "hidden" : false,
             "priority" : 3,
             "tags" : {            
             },
             "slaveDelay" : NumberLong(0),
             "votes" : 1
         },
         {
             "_id" : 1,
             "host" : "192.168.10.42:27017",
             "arbiterOnly" : false,
             "buildIndexes" : true,
             "hidden" : false,
             "priority" : 2,
             "tags" : {        
             },
             "slaveDelay" : NumberLong(0),
             "votes" : 1
         },
         {
             "_id" : 2,
             "host" : "192.168.10.43:27017",
             "arbiterOnly" : false,
             "buildIndexes" : true,
             "hidden" : false,
             "priority" : 1,
             "tags" : {                
             },
             "slaveDelay" : NumberLong(0),
             "votes" : 1
         }
     ],
     "settings" : {
         "chainingAllowed" : true,
         "heartbeatIntervalMillis" : 2000,
         "heartbeatTimeoutSecs" : 10,
         "electionTimeoutMillis" : 10000,
         "catchUpTimeoutMillis" : -1,
         "catchUpTakeoverDelayMillis" : 30000,
         "getLastErrorModes" : {    
         },
         "getLastErrorDefaults" : {
             "w" : 1,
             "wtimeout" : 0
         },
         "replicaSetId" : ObjectId("5f32312d4911b68cdaac02a6")
     }
 }
 rstest:PRIMARY>


(三)確認日誌保存狀況
oplog是一個上限集合,當數據量達到必定大小後,MongoDB會自動清理oplog日誌信息,爲了保證恢復可以正常進行,須要確認日誌的時間是否符合還原需求。簡單來講,oplog應該保存着自上一次備份以來的全部日誌。可使用下面方法來確認最先的oplog。
方法:查看主從複製信息
在主節點查看日誌信息,能夠看到oplog日誌大小,由於oplog是一個固定大小的集合,因此還能夠看到日誌的開始、結束時間、oplog的時間差等。數據庫

rstest:PRIMARY> db.printReplicationInfo()
configured oplog size:   1687.392822265625MB
 log length start to end: 246186secs (68.39hrs)
 oplog first event time:  Tue Aug 11 2020 13:48:29 GMT+0800 (CST)
 oplog last event time:   Fri Aug 14 2020 10:11:35 GMT+0800 (CST)
 now:                     Fri Aug 14 2020 10:11:36 GMT+0800 (CST)


(四)模擬將MongoDB恢復到任意時間點
(4.1)案例一:將整個實例恢復到某個時間點
(4.1.1)故障場景描述
業務人員發現多個MongoDB數據庫均存在數據錯誤的狀況,須要將所有數據恢復到過去的某個時刻。json


(4.1.2)數據恢復方法描述
只要肯定了恢復時間點,就可使用徹底備份+oplog備份,將數據恢復到過去的某個時刻。測試


(4.1.3)恢復過程
STEP1:模擬業務正常運行,數據正常進入MongoDB數據庫ui

use db1
db.db1test.insert({id:1,name:'a'})
db.db1test.insert({id:2,name:'b'})

use db2
db.db2test.insert({id:11,name:'aa'})
db.db2test.insert({id:22,name:'bb'})

STEP2:執行完整備份spa

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -o /root/backup/full

STEP3:再次模擬業務正常運行,數據正常進入MongoDB數據庫rest

use db1
db.db1test.insert({id:3,name:'c'})

use db2
db.db2test.insert({id:33,name:'cc'})

最終數據以下:日誌

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 1, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 2, "name" : "b" }
{ "_id" : ObjectId("5f35f57409eccc387e65cd8a"), "id" : 3, "name" : "c" }

rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd88"), "id" : 11, "name" : "aa" }
{ "_id" : ObjectId("5f35f4ee09eccc387e65cd89"), "id" : 22, "name" : "bb" }
{ "_id" : ObjectId("5f35f57509eccc387e65cd8b"), "id" : 33, "name" : "cc" }

STEP4:模擬數據誤操做code

# db1的db1test集合id增長100
use db1
db.db1test.update({},{$inc:{"id":100}},{multi:true})

# db2的db2test集合被刪除
use db2
db.db2test.drop()

錯誤執行以後的結果:

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 101, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 102, "name" : "b" }
{ "_id" : ObjectId("5f35f57409eccc387e65cd8a"), "id" : 103, "name" : "c" }

rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
rstest:PRIMARY>

要求把全部數據庫的數據恢復到STEP4以前的狀態。

STEP5:中止業務,再也不往數據庫寫數據

STEP6:備份日誌。能夠備份部分日誌,也能夠備份所有日誌

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -d local -c oplog.rs -o /root/backup/oplog/

STEP7:確認數據異常時間點,對oplog集合進行分析

use local

db.oplog.rs.find(
 {
     $and : [
      {"ns" : /db1/},
      {"op" : "u" }
     ]
  }
).sort({ts:1})

查詢結果以下,能夠確認,開始對db1.db1test集合更新的時間爲Timestamp(1597371835, 2)

/* 1 */
{
    "ts" : Timestamp(1597371835, 2),
    "t" : NumberLong(7),
    "h" : NumberLong(0),
    "v" : 2,
    "op" : "u",
    "ns" : "db1.db1test",
    "ui" : UUID("b3566a31-f6c1-4052-82a9-90f70728c41c"),
    "o2" : {
        "_id" : ObjectId("5f35f4ed09eccc387e65cd86")
    },
    "wall" : ISODate("2020-08-14T02:23:55.576Z"),
    "o" : {
        "$v" : 1,
        "$set" : {
            "id" : 101.0
        }
    }
}
/* 2 */
{
    "ts" : Timestamp(1597371835, 3),
    "t" : NumberLong(7),
    "h" : NumberLong(0),
    "v" : 2,
    "op" : "u",
    "ns" : "db1.db1test",
    "ui" : UUID("b3566a31-f6c1-4052-82a9-90f70728c41c"),
    "o2" : {
        "_id" : ObjectId("5f35f4ed09eccc387e65cd87")
    },
    "wall" : ISODate("2020-08-14T02:23:55.578Z"),
    "o" : {
        "$v" : 1,
        "$set" : {
            "id" : 102.0
        }
    }
}
/* 3 */
{
    "ts" : Timestamp(1597371835, 4),
    "t" : NumberLong(7),
    "h" : NumberLong(0),
    "v" : 2,
    "op" : "u",
    "ns" : "db1.db1test",
    "ui" : UUID("b3566a31-f6c1-4052-82a9-90f70728c41c"),
    "o2" : {
        "_id" : ObjectId("5f35f57409eccc387e65cd8a")
    },
    "wall" : ISODate("2020-08-14T02:23:55.578Z"),
    "o" : {
        "$v" : 1,
        "$set" : {
            "id" : 103.0
        }
    }
}

STEP8:執行徹底備份的恢復
須要注意,考慮是否須要使用"--drop"選項,若是不用該選項,會保留集合中當前的數據,若是使用了drop選項,在導入集合時會先刪除集合。這裏使用該選項

mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 --drop  /root/backup/full/

確認全量恢復的數據,已經恢復回來

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 1, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 2, "name" : "b" }
rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd88"), "id" : 11, "name" : "aa" }
{ "_id" : ObjectId("5f35f4ee09eccc387e65cd89"), "id" : 22, "name" : "bb" }
rstest:PRIMARY>

STEP9:使用oplog執行增量恢復
在恢復oplog以前,須要對其格式進行處理,不然會報錯

[root@node1 local]# mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 --oplogReplay --oplogLimit "1597371835:2" /root/backup/oplog/local
2020-08-14T10:44:45.120+0800    preparing collections to restore from
2020-08-14T10:44:45.120+0800    don't know what to do with file "/root/backup/oplog/local/oplog.rs.bson", skipping...
2020-08-14T10:44:45.120+0800    don't know what to do with file "/root/backup/oplog/local/oplog.rs.metadata.json", skipping...
2020-08-14T10:44:45.120+0800    Failed: no oplog file to replay; make sure you run mongodump with --oplog
2020-08-14T10:44:45.120+0800    0 document(s) restored successfully. 0 document(s) failed to restore.

須要把oplog.rs.metadata.json 文件刪除,把oplog.rs.bson名字改成oplog.bson

[root@node1 local]# ls
oplog.rs.bson  oplog.rs.metadata.json
[root@node1 local]# pwd
/root/backup/oplog/local
[root@node1 local]# rm -rf oplog.rs.metadata.json 
[root@node1 local]# mv oplog.rs.bson oplog.bson
[root@node1 local]# ls
 oplog.bson

最後執行oplog增量恢復便可

# 權限有問題,lijiaman用戶具備root角色
mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 --oplogReplay --oplogLimit "1597371835:2" /root/backup/oplog/local

# 執行成功
[root@node1 local]# mongorestore --authenticationDatabase admin -uroot2 -p123456 --port=27017 --oplogReplay --oplogLimit "1597371835:2" /root/backup/oplog/local

關於恢復權限,在MongoDB2.7也有相同的問題,見上一篇文檔

STEP10:確認數據恢復狀況,發現數據以及恢復到了STEP4以前的狀態

rstest:PRIMARY> use db1
switched to db db1
rstest:PRIMARY> db.db1test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd86"), "id" : 1, "name" : "a" }
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd87"), "id" : 2, "name" : "b" }
{ "_id" : ObjectId("5f35f57409eccc387e65cd8a"), "id" : 3, "name" : "c" }
rstest:PRIMARY> 
rstest:PRIMARY> use db2
switched to db db2
rstest:PRIMARY> db.db2test.find()
{ "_id" : ObjectId("5f35f4ed09eccc387e65cd88"), "id" : 11, "name" : "aa" }
{ "_id" : ObjectId("5f35f4ee09eccc387e65cd89"), "id" : 22, "name" : "bb" }
{ "_id" : ObjectId("5f35f57509eccc387e65cd8b"), "id" : 33, "name" : "cc" }
rstest:PRIMARY>

至此恢復結束。


(4.2)案例二:誤刪除某個DB,對單個DB進行恢復
一般,每一個DB承載不一樣的業務,相互之間沒有關係,若是出現故障,每每會表如今某個DB上,所以,若是出現故障,只對相應的DB進行恢復,那將減少對業務的影響。
(4.2.1)故障場景描述
假設業務運行過程當中,數據庫db3被人誤刪除了,咱們須要對db3進行恢復,而且不能影響到其它的DB業務。


(4.2.2)數據恢復方法描述
能夠在當前實例上進行恢復,也能夠新啓動一個mongod實例,用於數據恢復,咱們採用新的mongod實例來恢復數據。
1.首先新啓動一個mongod實例;
2.將已有的徹底備份恢復到新的實例上;
3.備份oplog,只備份db3的oplog,其它數據庫的不備份;
4.使用oplog將數據庫恢復到刪除以前;
5.檢查db3數據庫的數據,確認是否恢復回來;
6.若是第5步沒有問題,mongodump導出db3數據庫,而後倒入到生產環境中。


(4.2.3)恢復過程
STEP1:模擬業務正常運行,數據正常進入MongoDB數據庫

use db3
db.db3test.insert({id:111,name:'aaa'})
db.db3test.insert({id:222,name:'bbb'})
db.db3test.insert({id:333,name:'ccc'})

STEP2:執行完整備份

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -o /root/backup/full

STEP3:再次模擬業務正常運行,數據正常進入MongoDB數據庫

use db3
db.db3test.insert({id:444,name:'ddd'})
db.db3test.insert({id:555,name:'eee'})
db.db3test.insert({id:666,name:'fff'})

最終數據以下:

rstest:PRIMARY> db.db3test.find()
{ "_id" : ObjectId("5f35fff809eccc387e65cd8c"), "id" : 111, "name" : "aaa" }
{ "_id" : ObjectId("5f35fff809eccc387e65cd8d"), "id" : 222, "name" : "bbb" }
{ "_id" : ObjectId("5f35fff909eccc387e65cd8e"), "id" : 333, "name" : "ccc" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd8f"), "id" : 444, "name" : "ddd" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd90"), "id" : 555, "name" : "eee" }
{ "_id" : ObjectId("5f3600b409eccc387e65cd91"), "id" : 666, "name" : "fff" }
rstest:PRIMARY>

STEP4:模擬數據誤操做

rstest:PRIMARY> db
db3
rstest:PRIMARY> 
rstest:PRIMARY> 
rstest:PRIMARY> db.dropDatabase()
{
    "dropped" : "db3",
    "ok" : 1,
    "$clusterTime" : {
        "clusterTime" : Timestamp(1597374734, 2),
        "signature" : {
            "hash" : BinData(0,"0uoicASFK0ppoNhIEuURwElt7Qk="),
            "keyId" : NumberLong("6859599294731649027")
        }
    },
    "operationTime" : Timestamp(1597374734, 2)
}
rstest:PRIMARY>

接下來執行恢復操做。

STEP5:在發現誤操做以後,首先應該備份oplog,這裏只涉及到db3數據庫,只要備份db3的oplog便可,這樣能夠加快備份恢復速度

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -d local -c oplog.rs -q '{"ns":{"$regex":"db3"}}'  -o /root/backup/oplog/

STEP6:先執行徹底恢復

mongorestore --authenticationDatabase admin -ulijiaman -plijiaman  --port=27017 -d db3 /root/backup/full/db3

執行恢復後,db3數據已經恢復到了全備時的狀態

rstest:PRIMARY> show dbs
admin        0.000GB
config       0.000GB
db1          0.000GB
db2          0.000GB
db3          0.000GB
lijiamandb   0.000GB
local        0.002GB
maxiangqian  0.000GB
rstest:PRIMARY> 
rstest:PRIMARY> use db3
switched to db db3
rstest:PRIMARY> show collections
db3test
rstest:PRIMARY> db.db3test.find()
{ "_id" : ObjectId("5f35fff809eccc387e65cd8c"), "id" : 111, "name" : "aaa" }
{ "_id" : ObjectId("5f35fff809eccc387e65cd8d"), "id" : 222, "name" : "bbb" }
{ "_id" : ObjectId("5f35fff909eccc387e65cd8e"), "id" : 333, "name" : "ccc" }

STEP7:使用oplog恢復到drop操做以前
先確認drop db3數據庫的時間點:Timestamp(1597374734, 2)

use local
db.oplog.rs.find(
 {
     $and : [
      {"ns" : {"$regex":"db3"}},
      {"op" : "c"},
      {"o"  : {"dropDatabase":1}}
     ]
  }
).sort({ts:1})

結果以下

/* 1 */
{
    "ts" : Timestamp(1597374734, 2),
    "t" : NumberLong(7),
    "h" : NumberLong(0),
    "v" : 2,
    "op" : "c",
    "ns" : "db3.$cmd",
    "wall" : ISODate("2020-08-14T03:12:14.206Z"),
    "o" : {
        "dropDatabase" : 1
    }
}

執行增量恢復:

# 先處理oplog,刪除文件oplog.rs.metadata.json,修改oplog.rs.bson爲oplog.bson
[root@node1 local]# pwd
/root/backup/oplog/local
[root@node1 local]# ls
oplog.rs.bson  oplog.rs.metadata.json
[root@node1 local]# rm -rf oplog.rs.metadata.json 
[root@node1 local]# mv oplog.rs.bson oplog.bson 
[root@node1 local]# ls
oplog.bson

# 執行恢復
mongorestore --authenticationDatabase admin -ulijiaman -plijiaman  --port=27017  --oplogReplay --oplogLimit "1597374734:1" /root/backup/oplog/local

特別注意:這裏發現,oplogLimit參數,在MongoDB 2.7版本中不包含後面的時間點,在4.2裏面包含後面的時間點。若是我使用時間Timestamp(1597374734, 2)來做爲恢復點,則發現數據庫恢復完成又被刪除了。

檢查數據是否已經恢復,能夠確認,數據已經恢復回來

rstest:PRIMARY> db.db3test.find()
{ "_id" : ObjectId("5f35fff809eccc387e65cd8c"), "id" : 111, "name" : "aaa" }
{ "_id" : ObjectId("5f35fff809eccc387e65cd8d"), "id" : 222, "name" : "bbb" }
{ "_id" : ObjectId("5f35fff909eccc387e65cd8e"), "id" : 333, "name" : "ccc" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd8f"), "id" : 444, "name" : "ddd" }
{ "_id" : ObjectId("5f3600b309eccc387e65cd90"), "id" : 555, "name" : "eee" }
{ "_id" : ObjectId("5f3600b409eccc387e65cd91"), "id" : 666, "name" : "fff" }


(4.3)案例三:誤操做某個集合,對單個集合進行恢復
(4.3.1)故障場景描述
業務人員執行誤刪操DBA對數據進行恢復,詳細過程以下:
T1~T2:業務正常運行,數據正常進入數據庫
T2:使用mongodump執行數據庫徹底備份
T2~T4:業務正常運行,數據正常進入數據庫
T4:用戶誤刪除數據
T4~T6:業務還在運行,可是已經出現問題,如此時還能正常插入數據,可是查詢、更新、刪除數據存在找不到數據的錯誤
T6:DBA介入數據恢復


(4.3.2)數據恢復方法描述
能夠在當前實例上進行恢復,也能夠新啓動一個mongod實例,用於數據恢復,咱們在上一個例子中已經使用新建mongod實例的方式來恢復數據,本次實驗咱們直接在生產實例上進行恢復。
1.執行徹底恢復,使用徹底備份,將數據庫恢復到T2時刻;
2.找到T4時刻故障以前的時間,從而肯定T2~T4之間的oplog日誌。結合T2時刻的全備+ T2~T4之間的oplog日誌,實現數據恢復;(備註:這裏不須要去確認T2以後的日誌開始時間,在使用oplog恢復數據時,是經過惟一編號「_id」來操做數據的,oplog可能從全備份以前的任意時間開始,可是並不影響數據的正確性)。
3.找到T4時刻故障以後的時間,備份oplog。
4.使用oplog,實現T4~T6時間段的恢復。


(4.3.3)恢復過程
STEP1:模擬業務正常運行,數據正常進入MongoDB數據庫

use db4
db.db4test.insert({id:1111,name:'aaaa'})
db.db4test.insert({id:2222,name:'bbbb'})
db.db4test.insert({id:3333,name:'cccc'})

STEP2:執行完整備份

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -o /root/backup/full

STEP3:再次模擬業務正常運行,數據正常進入MongoDB數據庫

use db4
db.db4test.insert({id:4444,name:'dddd'})
db.db4test.insert({id:5555,name:'eeee'})
db.db4test.insert({id:6666,name:'ffff'})

最終數據以下:

rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd96"), "id" : 5555, "name" : "eeee" }
{ "_id" : ObjectId("5f3628c909eccc387e65cd97"), "id" : 6666, "name" : "ffff" }
rstest:PRIMARY>

STEP4:模擬數據誤操做,刪除2條數據

rstest:PRIMARY> db.db4test.remove({id:{$gt:4444}})
WriteResult({ "nRemoved" : 2 })

rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }

STEP5:再次模擬業務正常運行,數據正常進入MongoDB數據庫

use db4
db.db4test.insert({id:7777,name:'gggg'})
db.db4test.insert({id:8888,name:'hhhh'})
db.db4test.insert({id:9999,name:'kkkk'})

最終數據以下:

rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd98"), "id" : 7777, "name" : "gggg" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd99"), "id" : 8888, "name" : "hhhh" }
{ "_id" : ObjectId("5f3639a109eccc387e65cd9a"), "id" : 9999, "name" : "kkkk" }

此時,咱們發現id爲5555和6666的數據是被誤刪除的,須要恢復回來,而且要保留執行刪除命令以後的數據。

STEP6:在發現誤操做以後,首先應該備份oplog,這裏只涉及到db4.db4test集合,只要備份該集合的oplog便可,這樣能夠加快備份恢復速度

mongodump --authenticationDatabase admin -ulijiaman -plijiaman -d local -c 'oplog.rs' -q '{"ns":"db4.db4test"}'  -o /root/backup/oplog/

STEP7:對該集合執行徹底恢復操做

mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017 -d db4 -c db4test  /root/backup/full/db4/db4test.bson

STEP8:使用oplog,對該集合執行增量恢復操做
先查看對db4.db4test集合執行刪除的開始時間Timestamp(1597389188, 1)

use local
db.oplog.rs.find(
 {
     $and : [
      {"ns" : /db4.db4test/},
      {"op" : "d" }
     ]
  }
).sort({ts:1})


/* 1 */
{
    "ts" : Timestamp(1597389188, 1),
    "t" : NumberLong(7),
    "h" : NumberLong(0),
    "v" : 2,
    "op" : "d",
    "ns" : "db4.db4test",
    "ui" : UUID("75507280-3f74-4c17-a3f7-46ce7087c08a"),
    "wall" : ISODate("2020-08-14T07:13:08.162Z"),
    "o" : {
        "_id" : ObjectId("5f3628c809eccc387e65cd96")
    }
}
/* 2 */
{
    "ts" : Timestamp(1597389188, 2),
    "t" : NumberLong(7),
    "h" : NumberLong(0),
    "v" : 2,
    "op" : "d",
    "ns" : "db4.db4test",
    "ui" : UUID("75507280-3f74-4c17-a3f7-46ce7087c08a"),
    "wall" : ISODate("2020-08-14T07:13:08.162Z"),
    "o" : {
        "_id" : ObjectId("5f3628c909eccc387e65cd97")
    }
}

執行增量恢復:

# 先處理oplog,刪除文件oplog.rs.metadata.json,修改oplog.rs.bson爲oplog.bson
[root@mongo1 local]# pwd
/root/backup/oplog/local
[root@mongo1 local]# rm -rf oplog.rs.metadata.json
[root@mongo1 local]# mv oplog.rs.bson oplog.bson
[root@mongo1 local]# ls
oplog.bson

# 執行恢復
mongorestore --authenticationDatabase admin -ulijiaman -plijiaman --port=27017  --oplogReplay --oplogLimit "1597389188:1" /root/backup/oplog/local

STEP9:查看數據是否恢復,確認已經徹底恢復回來

rstest:PRIMARY> db.db4test.find()
{ "_id" : ObjectId("5f36267a09eccc387e65cd92"), "id" : 1111, "name" : "aaaa" }
{ "_id" : ObjectId("5f36267a09eccc387e65cd93"), "id" : 2222, "name" : "bbbb" }
{ "_id" : ObjectId("5f36267b09eccc387e65cd94"), "id" : 3333, "name" : "cccc" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd95"), "id" : 4444, "name" : "dddd" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd98"), "id" : 7777, "name" : "gggg" }
{ "_id" : ObjectId("5f3639a009eccc387e65cd99"), "id" : 8888, "name" : "hhhh" }
{ "_id" : ObjectId("5f3639a109eccc387e65cd9a"), "id" : 9999, "name" : "kkkk" }
{ "_id" : ObjectId("5f3628c809eccc387e65cd96"), "id" : 5555, "name" : "eeee" }
{ "_id" : ObjectId("5f3628c909eccc387e65cd97"), "id" : 6666, "name" : "ffff" }


【完】


相關文檔:

1.MongoDB 2.7主從複製(master –> slave)環境基於時間點的恢復  
2.MongoDB 4.2副本集環境基於時間點的恢復


3.MongoDB恢復探究:爲何oplogReplay參數只設置了日誌應用結束時間oplogLimit,而沒有設置開始時間?

相關文章
相關標籤/搜索