修改并重播MongoDB oplog

是否有可能修改MongoDB oplog并重播它?

一个错误导致更新被应用到更多的文件比它应该是,覆盖一些数据。 数据从备份恢复并重新集成,所以没有什么实际上丢失,但我想知道是否有办法修改oplog删除或修改违规的更新和重播。

我没有对MongoDB内部知识的深入了解,所以大致的答案,“你不明白它是如何工作的,就是这样”也将被考虑接受。

应用程序或人为错误数据损坏中的一个重大问题是,对主服务器的有问题的写入将立即被复制到辅助服务器。

这是用户利用“slaveDelay”的原因之一 – 这是一个可以固定时间延迟运行一个辅助节点的选项(当然,如果在短时间内发现错误或缺陷,该次要的延迟)。

如果您没有这样的设置,则必须依靠备份来重新创build需要恢复到预先错误状态的logging状态。

只有在确认所有事情都已正确重新创build之后,才可以将更正后的数据移动到您的生产系统中,然后在单独的数据副本上执行所有操作。

要做到这一点,需要备份的最近副本(假设备份是X小时),并且群集上的oplog必须保存超过X小时的数据。 我没有指定哪个节点的oplog,因为(a)副本集的每个成员在oplog中都有相同的内容,(b)在不同的节点成员上oplog的大小可能不同,在这种情况下, “最大”的一个。

所以假设你最近的备份是52个小时,但幸运的是你有一个可以存储75小时数据的oplog(yay)。

你已经意识到所有的节点(主节点和次节点)都有“坏”的数据,所以你要做的就是将这个最新的备份恢复到新的mongod中。 这是您将这些logging恢复到正确的更新之前的位置 – 然后您可以将它们移动到当前的主要位置,从那里将它们复制到所有次级服务器。

在恢复备份时,通过以下命令创buildoplog集合的mongodump:

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

将oplog移动到其自己的目录,将其重命名为oplog.bson:

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

现在你需要find“违规”操作。 您可以使用oplogR / oplog.bson文件上的bsondump命令(然后使用grep或what-notfind“bad”更新)将oplog转储为可读的forms。 或者,您可以通过在shell中use localdb.oplog.rs.find()命令来查询副本集中的原始oplog。

你的目标是find这个条目,并注意它的ts字段。

它可能看起来像这样:

"ts" : Timestamp( 1361497305, 2789 )

请注意, mongorestore命令有两个选项,一个叫做--oplogReplay ,另一个叫oplogLimit 。 您现在将在已恢复的独立服务器上重播此oplog,但在此违规更新操作之前您将停止。

该命令将是(主机和端口是你最近恢复的备份):

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

这将从oplogR目录中的oplog.bson文件中恢复每个操作,正好在ts值为Timestamp(1361497305,2789)的条目之前停止。

回想一下,你在一个单独的实例上这样做的原因是,你可以validation恢复和重放创build正确的数据 – 一旦你已经validation,那么你可以写恢复的logging到实际的主要适当的地方(并允许复制传播更正的logging给二手)。