简体   繁体   English

修改并重放MongoDB oplog

[英]Modify and replay MongoDB oplog

Is it possible to modify the MongoDB oplog and replay it? 是否可以修改MongoDB oplog并重放它?

A bug caused an update to be applied to more documents than it was supposed to be, overwriting some data. 一个错误导致更新应用于比预期更多的文档,覆盖一些数据。 Data was recovered from backup and reintegrated, so nothing was actually lost, but I was wondering if there was a way to modify the oplog to remove or modify the offending update and replay it. 数据从备份和重新集成中恢复,因此实际上没有丢失,但我想知道是否有办法修改oplog以删除或修改有问题的更新并重播它。

I don't have in depth knowledge of MongoDB internals, so informative answers along the lines of, "you don't understand how it works, it's like this" will also be considered for acceptance. 我没有深入了解MongoDB内部的知识,因此,“你不明白它是如何工作的,它就像这样”的信息性答案也将被考虑接受。

One of the big issues in application or human error data corruption is that the offending write to the primary will immediately be replicated to the secondary. 应用程序或人为错误数据损坏的一个重大问题是,对主数据库的违规写入将立即复制到辅助数据库。

This is one of the reasons that users take advantage of "slaveDelay" - an option to run one of your secondary nodes with a fixed time delay (of course that only helps you if you discover the error or bug during the time period that's shorter than the delay on that secondary). 这是用户利用“slaveDelay”的一个原因 - 一个选项以固定的时间延迟运行您的一个辅助节点(当然,如果您发现错误或错误的时间短于中学的延迟)。

In case you don't have such a set-up, you have to rely on a backup to recreate the state of the records you need to restore to their pre-bug state. 如果您没有这样的设置,则必须依靠备份来重新创建需要恢复到其bug前状态的记录的状态。

Perform all the operations on a separate stand-alone copy of your data - only after verifying that everything was properly recreated should you then move the corrected data into your production system. 在单独的数据独立副本上执行所有操作 - 只有在验证所有内容都已正确重新创建后才能将更正后的数据移动到生产系统中。

What is required to be able to do this is a recent copy of the backup (let's say the backup is X hours old) and the oplog on your cluster must hold more than X hours worth of data. 能够执行此操作所需的是备份的最新副本(假设备份是X小时),并且群集上的oplog必须保存超过X小时的数据。 I didn't specify which node's oplog because (a) every member of the replica set has the same contents in the oplog and (b) it is possible that your oplog size is different on different node members, in which case you want to check the "largest" one. 因为(a)中的副本组的每一个成员都有在OPLOG和相同的内容我没有指定哪个节点的OPLOG(B) 可能是你的OPLOG大小是不同的节点成员不同,在这种情况下,要检查“最大的”。

So let's say your most recent backup is 52 hours old, but luckily you have an oplog that holds 75 hours worth of data (yay). 所以,假设你最近的备份是52小时,但幸运的是你有一个oplog,可以保存75个小时的数据(yay)。

You already realized that all of your nodes (primary and secondaries) have the "bad" data, so what you would do is restore this most recent backup into a new mongod. 您已经意识到所有节点(主节点和辅助节点)都有“坏”数据,因此您要做的是将此最新备份还原为新的mongod。 This is where you will restore these records to what they were right before the offending update - and then you can just move them into the current primary from where they will get replicated to all the secondaries. 在这里,您可以将这些记录恢复到违规更新之前的状态 - 然后您可以将它们移动到当前主数据库中,从而将它们复制到所有辅助数据库。

While restoring your backup, create a mongodump of your oplog collection via this command: 在恢复备份时,通过以下命令创建oplog集合的mongodump:

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

Move the oplog to its own directory renaming it to oplog.bson: 将oplog移动到自己的目录,将其重命名为oplog.bson:

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

Now you need to find the "offending" operation. 现在你需要找到“冒犯”的操作。 You can dump out the oplog to human readable form, using the bsondump command on oplogR/oplog.bson file (and then use grep or what-not to find the "bad" update). 您可以使用oplogR / oplog.bson文件上的bsondump命令将oplog转储为人类可读的形式(然后使用grep或what-not来查找“错误”更新)。 Alternatively you can query against the original oplog in the replica set via use local and db.oplog.rs.find() commands in the shell. 或者,您可以通过在shell中use localdb.oplog.rs.find()命令来查询副本集中的原始oplog。

Your goal is to find this entry and note its ts field. 您的目标是找到此条目并记下其ts字段。

It might look like this: 它可能看起来像这样:

"ts" : Timestamp( 1361497305, 2789 )

Note that the mongorestore command has two options, one called --oplogReplay and the other called oplogLimit . 请注意, mongorestore命令有两个选项,一个名为--oplogReplay ,另一个名为oplogLimit You will now replay this oplog on the restored stand-alone server BUT you will stop before this offending update operation. 您现在将在已恢复的独立服务器上重播此oplog但您将在此违规更新操作之前停止。

The command would be (host and port are where your newly restored backup is): 该命令将是(主机和端口是新恢复的备份的位置):

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

This will restore each operation from the oplog.bson file in oplogR directory stopping right before the entry with ts value Timestamp(1361497305, 2789). 这将从oplogR目录中的oplog.bson文件恢复每个操作,该文件在具有ts值Timestamp(1361497305,2789)的条目之前停止。

Recall that the reason you were doing this on a separate instance is so you can verify the restore and replay created correct data - once you have verified it then you can write the restored records to the appropriate place in the real primary (and allow replication propagate the corrected records to the secondaries). 回想一下,您在单独的实例上执行此操作的原因是,您可以验证还原并重播创建的正确数据 - 一旦您验证了它,您就可以将还原的记录写入真实主数据库中的适当位置(并允许复制传播)更正的记录到次要的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM