有什么方法可以恢复MongoDB中最近删除的文档?

问题描述 投票:18回答:2

我错误地删除了上一个查询中的一些文档,有没有办法回滚我的上一个查询mongo集合。

这是我的最后一个查询:

 db.datas.remove({ "name" : "some_x_name"}) 

是否有任何回滚/撤消选项?我可以取回我的数据吗?

mongodb rollback
2个回答
25
投票

没有回滚选项(在MongoDB上下文中为rollback has a different meaning),严格来说,没有返回这些文档的支持方法-注释中涵盖了您可以/应该采取的预防措施。如此说来,如果您正在运行副本集,甚至是单节点副本集,那么您都将拥有一个oplog。用oplog遮盖插入文档的时间,您也许可以将其恢复。

最简单的方法是举一个例子。我将使用一个简化的示例,其中仅包含100个需要还原的已删除文档。要超出此范围(大量文档,或者您可能只希望选择性地还原等),您可能想要更改代码以遍历游标,或者在MongoDB shell之外使用您选择的语言编写此代码。基本逻辑保持不变。

首先,让我们在数据库oplog中创建示例集合foo。我们将插入100个没有dropTest字段的文档和100个具有相同name字段的文档,以便以后可以将它们错误地删除:

name

现在,让我们模拟一下意外删除了100个use dropTest; for(i=0; i < 100; i++){db.foo.insert({_id : i})}; for(i=100; i < 200; i++){db.foo.insert({_id : i, name : "some_x_name"})}; 文档:

name

由于我们在副本集中运行,因此我们仍在> db.foo.remove({ "name" : "some_x_name"}) WriteResult({ "nRemoved" : 100 }) 中记录了这些文档(正在插入),并且值得庆幸的是,这些插入还没有(还)落在oplog的末尾([C0 ]是oplog记住)。让我们看看是否可以找到它们:

oplog

该计数看起来正确,我们似乎仍在保存文件。从经验中我知道,我们在这里需要的capped collection条目的唯一部分是use local; db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}).count(); 100 字段,所以让我们添加一个投影以仅返回该投影(为简洁起见,输出被删节,但您明白了):

oplog

要重新插入这些文档,我们可以将它们存储在一个数组中,然后遍历该数组并插入相关的片段。首先,让我们创建数组:

o

接下来,我们提醒自己,我们现在在集合中只有100个文档,然后遍历100个插入,最后重新验证计数:

db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}, {"o" : 1});
{ "o" : { "_id" : 100, "name" : "some_x_name" } }
{ "o" : { "_id" : 101, "name" : "some_x_name" } }
{ "o" : { "_id" : 102, "name" : "some_x_name" } }
{ "o" : { "_id" : 103, "name" : "some_x_name" } }
{ "o" : { "_id" : 104, "name" : "some_x_name" } }

这里有警告,请注意:

  • 这并不意味着是真正的恢复策略,请查看备份(MMS,其他),为此目的延迟备份,如评论中所述
  • 在大型繁忙的系统上,从oplog中查询文档(任何oplog查询都是表扫描)并不是特别快。
  • 文档可能会随时在oplog中过期(当然,您可以复制oplog以便以后使用,以给您更多时间)
  • 根据您的工作量,可能需要在重新插入结果之前对结果进行重复数据删除
  • 较大的文档集对于一个数组来说太大了,因此您需要遍历游标而不是]
  • var deletedDocs = db.oplog.rs.find({op : "i", ns : "dropTest.foo", "o.name" : "some_x_name"}, {"o" : 1}).toArray(); > deletedDocs.length 100 的格式被认为是内部的,可能随时更改(恕不另行通知,因此使用后果自负)>

10
投票

虽然我知道这有点古老,但我想分享我在这一领域研究过的东西,可能对遇到类似问题的其他人有用。

© www.soinside.com 2019 - 2024. All rights reserved.