2013-03-16 46 views
43

是否可以修改MongoDB oplog並重播它?修改並重播MongoDB oplog

一個錯誤導致更新應用於更多的文檔,而不是它應該覆蓋的一些數據。數據從備份恢復並重新集成,所以沒有任何實際丟失,但我想知道是否有辦法修改oplog以刪除或修改違規更新並重播它。

我沒有在MongoDB中內部的深入瞭解,沿線的線,使信息的回答:「你不明白它是如何工作的,是這樣的」,也將被視爲驗收。

+0

從技術上講,它是'本地'數據庫中的上限集合,所以技術上你可以修改它中的行並重播它我認爲 – Sammaye 2013-03-16 10:31:42

+0

你不能對封頂的集合做很多事情,你可以對常規集合 - 例如,您無法刪除記錄以更改它們的大小來更新它們。雖然有實用程序可用於重放oplog。 – 2013-03-16 15:56:38

回答

91

應用程序或人爲錯誤數據損壞的一個主要問題是,對主服務器的違規寫入將立即被複制到輔助服務器。

這是用戶利用「slaveDelay」的原因之一 - 這是一個選項,可以以固定的時間延遲運行一個輔助節點(當然,只有當您在此期間發現錯誤或錯誤時纔會幫助您這段時間比該次要時間短)。

如果你沒有這樣的設置,你必須依靠備份來重新創建你需要恢復到錯誤前的狀態記錄的狀態。

執行對數據的單獨的獨立副本,所有的操作 - 只有在證實一切被正確地重新創建你應該將校正後的數據轉移到生產系統後。

需要什麼,能夠做,這是最近的備份副本(假設備份是X小時歲)和羣集上OPLOG必須持有超過X小時價值的數據更多。我沒有指定哪個節點的oplog,因爲(a)副本集的每個成員在oplog中具有相同的內容,並且(b)它可能在不同的節點成員上oplog大小不同,在這種情況下,您希望檢查「最大」的一個。

所以我們可以說最近的備份52小時大,但幸運的是,你必須持有75小時價值的數據(耶)的OPLOG。

您已經意識到所有節點(主節點和輔助節點)都有「壞」數據,因此您要做的就是將此最新備份恢復到新的mongod中。這是您將這些記錄還原到違規更新之前的正確位置的地方 - 然後您可以將它們移動到當前的主服務器中,從那裏將它們複製到所有輔助服務器。

同時恢復您的備份,通過這個命令創建OPLOG集合的mongodump:

mongodump -d local -c oplog.rs -o oplogD

移動OPLOG到自己的目錄重命名它oplog.bson:

mkdir oplogR 
mv oplogD/local/oplog.rs.bson oplogR/oplog.bson 

現在你需要找到「違規」操作。您可以使用oplogR/oplog.bson文件上的bsondump命令(然後使用grep或不能找到「錯誤」更新)將oplog轉儲爲可讀的形式。或者,您可以通過shell中的use localdb.oplog.rs.find()命令在副本集中查詢原始oplog。

你的目標是找到這個條目,並記下其ts場。

這可能是這樣的:

"ts" : Timestamp(1361497305, 2789)

注意,mongorestore命令有兩個選項,一個叫--oplogReplay另一種叫oplogLimit。您現在將在恢復的獨立服務器上重播此oplog,但在此違規更新操作之前,您將停止。

的命令是(主機和端口都在您的新恢復的備份):

mongorestore -h host --port NNNN --oplogReplay --oplogLimit 1361497305:2789 oplogR

這將從oplogR目錄中的條目之前正確停止oplog.bson文件還原每個操作ts值時間戳(1361497305,2789)。

回想一下,您在單獨實例上執行此操作的原因是您可以驗證還原並重播創建了正確的數據 - 一旦您驗證了它,則可以將還原的記錄寫入實際主數據的適當位置並允許複製將更正的記錄傳播給輔助部分)。

+0

謝謝,這正是我一直在尋找的。情況就像你所描述的那樣,一個延遲的節點已經複製了不好的更新。 – michaeltwofish 2013-03-16 18:00:47

+0

嗨。我是新來的Mongo,所以想知道這個本地數據庫是否存儲所有dbs和集合的oplog?如果我需要恢復單個數據庫或集合,如何過濾oplog中的條目? – gansbrest 2015-03-10 17:37:02

+0

每個mongod進程只有一個oplog。 – 2015-03-11 21:37:39