是否可以修改MongoDB oplog并重播它?
一个错误导致更新应用于比预期更多的文档,覆盖了一些数据。数据从备份恢复并重新集成,因此实际上没有丢失,但我想知道是否有办法修改oplog以删除或修改有问题的更新并重播它。
我没有深入了解MongoDB的内部知识,因此,“你不明白它是如何工作的,就像这样”的信息性答案也将被考虑接受。
答案 0 :(得分:96)
应用程序或人为错误数据损坏的一个重大问题是,对主数据库的违规写入将立即复制到辅助数据库。
这是用户利用“slaveDelay”的原因之一 - 一个以固定时间延迟运行其中一个辅助节点的选项(当然,如果您在此期间发现错误或错误,这只会对您有所帮助)这比次要的延迟要短。
如果您没有这样的设置,您必须依靠备份来重新创建需要恢复到其bug前状态的记录状态。
在单独的数据独立副本上执行所有操作 - 只有在验证所有内容都已正确重新创建后才能将更正的数据移动到生产系统中。
能够执行此操作所需的是备份的最新副本(假设备份是X小时),并且群集上的oplog必须保存超过X小时的数据。我没有指定哪个节点的oplog,因为(a)副本集的每个成员在oplog中具有相同的内容,(b) 可能是因为不同节点成员上的oplog大小不同,在这种情况下,你想检查“最大的”。
因此,假设您最近的备份是52小时,但幸运的是,您有一个oplog,可以保存75小时的数据(yay)。
您已经意识到所有节点(主节点和辅助节点)都有“坏”数据,因此您要做的是将此最新备份恢复为新的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
命令将oplog转储为人类可读的形式(然后使用grep或what-not来查找“错误”更新)。或者,您可以通过shell中的use local
和db.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值Timestamp(1361497305,2789)的条目之前停止。
回想一下,您在单独的实例上执行此操作的原因是,您可以验证还原并重播创建的正确数据 - 一旦您验证了它,您就可以将恢复的记录写入真实主数据库中的适当位置(和允许复制将更正的记录传播到辅助节点。)