2013-03-16 42 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