天天看點

mongodb 基于oplog的時間點恢複

本文簡單介紹mongodb時間點恢複的過程:

1.首先建立hezi集合,并插入10000條資料;

MongoDB Enterprise liuhe_rs:PRIMARY>use liuwenhe

MongoDB Enterprise liuhe_rs:PRIMARY>for (

var i = 0; i < 100000; i++) {

db.hezi.insert({id: i});

}

MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.count();

100000

2.執行備份操作,使用參數 --oplog ,會在備份路徑下産生oplog.bson檔案

[mongod@beijing-fuli-hadoop-01 backup]$ mongodump -h 10.9.21.179 -u liuwenhe -p

liuwenhe --authenticationDatabase admin --oplog -o /data/mongodb/backup/

假裝置份開始時間為 A 結束時間為B

3.等備份完成後,如果此時業務又insert了資料:

MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.insert({id: 100001});

WriteResult({ "nInserted" : 1 })

100001

4.在時間 C點,模拟誤删除操作

MongoDB Enterprise liuhe_rs:PRIMARY> db.hezi.remove({})

WriteResult({ "nRemoved" : 100001 })

5.那麼怎麼來恢複這個表呢?

這種情況下,應該首先停止業務,避免由于業務量大,導緻把oprlog給覆寫了,因為如果

oprlog被覆寫了,那麼你就無法恢複出db.hezi.insert({id: 100001})這條資料,因為這條資料

是在你備份完成後插入的資料,是以你需要立刻把oplog.rs集合給dump出來以便于進行時

間點恢複,

是以分兩種情況具體如下:

情況一:

你備份開始的時間點A 到 你誤删除的時間點C 這段時間的oplog.rs的資料沒有被覆寫

那麼就肯定能恢複出所有的資料!直接用你後來備份的oplog.rs替換你之前全備份的産生的

oplog.bson檔案!

情況二:(分成兩種情況)

如果你備份開始的時間點A 到 你誤删除的時間點C 這段時間的oplog.rs的資料被覆寫了,

那麼你就隻能先恢複你的全備,然後再從oplog.rs裡面盡可能找到更多的關于這個集合的

操作,然後應用,能不能全部恢複出資料,就看運氣了,這裡又有兩種情況:

情況1:備份結束B到誤删除C 這段時間内的oplog.rs沒有被覆寫,那麼就可以恢複出所有的資料

情況2:備份結束B到誤删除C 這段時間内的oplog.rs被覆寫,那麼就隻能期待關于這個

賣手遊

集合的操作

的oplog沒有被覆寫,這樣才能恢複出所有的資料!

怎麼去分辨到底有沒有被覆寫呢?

首先在你備份的機器上看,可以看出oplogs的開始和結束時間,當然這不一定準确,

MongoDB Enterprise liuhe_rs:PRIMARY> rs.printReplicationInfo()

configured oplog size: 51200MB

log length start to end: 1299939secs (361.09hrs)

oplog first event time: Sat Nov 16 2019 16:53:17 GMT+0800 (CST)

oplog last event time: Sun Dec 01 2019 17:58:56 GMT+0800 (CST)

now: Sun Dec 01 2019 17:59:02 GMT+0800 (CST)

最好還是從你單獨備份集合oplog.rs的備份檔案

oplog.rs.bson中去判斷:

格式化檔案oplog.rs.bson,以便于檢視時間

[mongod@beijing-fuli-hadoop-04 local]$ bsondump oplog.rs.bson >12

看備份中的oplog的開始時間

[mongod@beijing-fuli-hadoop-04 local]$ cat 12 | head

{"ts":{"$timestamp":{"t":1575040546,"i":1}},"t":{"$numberLong":"7"},"h":{"$numberLong":"-8378285387564165709"},"v":2,"op":"n","ns":"","wall":{"$date":"2019-11-29T15:15:46.661Z"},"o":{"msg":"Reconfig set","version":26}}

看備份中的oplog的結束時間

[mongod@beijing-fuli-hadoop-04 local]$ cat 12 | tail -n 1

同理再去檢視全備份的産生的oplog.bson中的開始時間和結束時間!就可以判斷出有沒有被覆寫了!

情況1:

1)dump出集合oplog.rs的資料

[mongod@beijing-fuli-hadoop-01 local]$ mongodump -h 10.9.21.179 -u liuwenhe -p liuwenhe --authenticationDatabase admin -d local -c oplog.rs -o /data/mongodb/liuwenhe/

[mongod@beijing-fuli-hadoop-01 local]$ pwd

/data/mongodb/liuwenhe/local

[mongod@beijing-fuli-hadoop-01 local]$ ll

total 60308

-rw-rw-r-- 1 mongod mongod 61751065 Nov 29 19:42

oplog.rs.bson

-rw-rw-r-- 1 mongod mongod 124 Nov 29 19:42 oplog.rs.metadata.json

2)然後找到删除hezi集合的開始時間, 當你删除某個集合的時候,她在oplogs中是一條一條的删除的!這個你可以使用bsondump格式化看看!

[mongod@beijing-fuli-hadoop-01 local]$ bsondump oplog.rs.bson | grep "\"op\":\"d\"" | grep liuwenhe.hezi |head

{"ts":{"$timestamp":{"t":1575025894,"i":1}},"t":{"$numberLong":"6"},"h":{"$numberLong":"2211936654694340159"},"v":2,"op":"d","ns":"liuwenhe.hezi","ui":{"$binary":"GG4MuSZBQpm4anq5TBp00Q==","$type":"04"},"wall":{"$date":"2019-11-29T11:11:34.499Z"},"o":{"_id":{"$oid":"5de0fb7cb54dce214bb40c7b"}}}

3)需要把 前面備份的oplog.rs.bson檔案替換全備份的檔案中的oplog.bson檔案,

這裡的oplog.rs.bson其實就是我們需要的oplog.bson。是以把它重命名後放到合适的位置!

[mongod@beijing-fuli-hadoop-03 /data/mongodb/backup/backup]$ rm -f oplog.bson

[mongod@beijing-fuli-hadoop-03 /data/mongodb/backup/backup]$mv oplog.rs.bson oplog.bson

其中oplog.rs.bson是你前面單獨備份的oplog.rs, 而oplog.bson是你全備份中帶參數

--oplog産生的檔案;

4)在另一個空閑執行個體上恢複出之前的全備份:

先把備份從21.114copy到21.115特定的目錄中:

scp -r backup/ [email protected]:/data/mongodb/backup/

然後進行恢複:

[mongod@beijing-fuli-hadoop-03 /data]$ mongorestore -h 10.9.21.115 -u liuwenhe -p liuwenhe --oplogReplay --oplogLimit "

1575025894

:1" --authenticationDatabase admin --dir /data/mongodb/backup/backup/

其中

1575025894即是$timestamp中的"t",

1即是$timestamp中的"i"。這樣配置後oplog将會

重放到這個時間點以前,即正好避開了第一條删除語句及其後面的操作,資料庫停留在災難

前狀态

驗證确實恢複出來了:

MongoDB Enterprise > db.hezi.count()

5)把恢複出來的資料在恢複到生産上去:

在21.115上備份:

mongodump -h 10.9.21.115 -u liuwenhe -p liuwenhe -d liuwenhe -dliuwenhe -c hezi --authenticationDatabase admin -o /data/mongodb/

在21.115上直接恢複,前提網絡通,如果不通的話,先把備份檔案copy到生産上。然後恢複:

[mongod@beijing-fuli-hadoop-04 li]$ mongorestore -h 10.9.21.114 -u liuwenhe -p liuwenhe -d liuwenhe -c hehe --noIndexRestore --authenticationDatabase admin --dir /data/mongodb/backup/li/hezi.bson

情況2中的第一種情況:

備份結束B到誤删除C 這段時間内的oplog.rs沒有被覆寫,那麼就可以恢複出所有的資料,具體

恢複過程如下:

1.恢複一緻性全備份:

[mongod@beijing-fuli-hadoop-03 /data]$ mongorestore -h 10.9.21.115 -u liuwenhe -p liuwenhe --oplogReplay --authenticationDatabase admin --dir /data/mongodb/backup/backup/

2.然後再繼續增量恢複oplog,從備份的oplog.rs檔案中找到删除hezi這個集合的時間點,因為opglog

的幂等性,可以重複執行也不會造成資料不一緻,是以沒必要在導出oplog.rs的時候選擇增量導出;

mongorestore -h 10.9.21.115 -u liuwenhe -p liuwenhe --oplogReplay --oplogLimit "

:1" --authenticationDatabase admin --dir /data/mongodb/backup/backup/local/oplog.rs.bson

情況2中的第二種情況:

備份結束B到誤删除C 這段時間内的oplog.rs被覆寫,那麼就隻能期待關于這個集合的操作

的oplog沒有被覆寫,這樣才能恢複出所有的資料!坦白講這種情況下,沒法确認到底關于

這個集合的操作的oplogs有沒有被覆寫,隻能先恢複看了,過程同情況2中的第一種情況;

綜上所述:

mongodb的時間點恢複的過程類似于mysql借助binlog的過程,但是差別是

mysql需要找到具體的 gtid點,增量恢複,但是mongodb的oplog是可以多次執行,這樣就使得

mongodb 借助oprlog的時候操作簡單些;