是否可以修改MongoDB oplog并重放它?
一个错误导致将更新应用于比预期更多的文档,从而覆盖了一些数据。数据已从备份中恢复并重新集成,因此实际上没有丢失任何内容,但我想知道是否有办法修改 oplog 以删除或修改有问题的更新并重放它。
我对 MongoDB 内部没有深入的了解,因此类似“你不明白它是如何工作的,就是这样”的信息性回答也将被考虑接受。
最佳答案
应用程序或人为错误数据损坏的一个大问题是对主节点的违规写入将立即复制到辅助节点。
这是用户利用“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
命令将 oplog 转储为人类可读的形式(然后使用 grep 或其他命令来查找“错误”更新)。或者,您可以通过 shell 中的 use local
和 db.oplog.rs.find()
命令查询副本集中的原始 oplog。
您的目标是找到此条目并记下它的 ts
字段。
它可能看起来像这样:
"ts": 时间戳(1361497305, 2789)
请注意,mongorestore
命令有两个选项,一个称为 --oplogReplay
,另一个称为 oplogLimit
。您现在将在恢复的独立服务器上重播此操作日志,但您将在此违规更新操作之前停止。
命令将是(主机和端口是您新恢复的备份所在的位置):
mongorestore -h host --port NNNN --oplogReplay --oplogLimit 1361497305:2789 oplogR
这将从 oplogR 目录中的 oplog.bson 文件中恢复每个操作,该文件在 ts 值为 Timestamp(1361497305, 2789) 的条目之前停止。
回想一下,您在单独的实例上执行此操作的原因是,您可以验证还原和重放创建的数据是否正确 - 一旦您验证了它,您就可以将还原的记录写入真实主实例中的适当位置(并且允许复制将更正的记录传播到辅助节点)。
https://stackoverflow.com/questions/15444920/