本文基于如下图时间轴说明按 Key 闪回并进行数据更新的操作过程。

数据准备
1. 若原集合名为
test,时间点 A,表里有三条数据,记录着三个人的分数(score),都是90分。
2. 时间点 C,对集合 test 中的三个人的分数(score)进行了更新,并增加了赵六的信息。

发现问题并发起按 Key 闪回
在时间点D发现张三、李四和赵六的分数数据异常,而王五的数据正常。为精准修复此问题,计划将这三人的数据状态恢复到早期的时间点B。通过使用按Key闪回功能,以唯一性的_id字段作为筛选条件,并分别填入三人的ID值,即可发起定向恢复任务。如下图的指定 Key 列表中选
_id,在输入条件值的输入框中分行输入_id信息(例如:ObjectId("652d2a6505726f***********")),发起按 Key 闪回任务。具体操作,请参见 发起按 Key 闪回任务。更新数据步骤
等待按 Key 闪回任务执行完成,可按照如下步骤更新数据。
步骤1:确认闪回集合中的数据完整可用,以及是否有目标时间点缺失记录集合。
1. 执行
show collections 查看是否生成了闪回集合或缺失记录集合。如图可见,操作生成了两个集合:test_bak1016151413 为闪回集合,存储了在目标时间点 B 已存在的指定 Key 所对应的数据快照。test_bak_missing1016151413 为缺失记录集合。用于记录那些在时间点 B 尚未写入、但在当前时间点 D 存在的指定 Key。
说明:
闪回集合名和缺失记录集合名中结尾的时间是操作时间,并非目标回档时间。
2. 利用按 Key 筛选的条件,分别计算 test 原集合、test_bak1016151413 闪回集合及其 test_bak_missing1016151413缺失集合的数据数目。
如下图所示,闪回集合里有2个,记录缺失集合里有1个,三条数据和原集合内的数据的
_id字段都是一致的,加起来数目也符合预期。

步骤2:对比闪回集合中的数据和原集合中的数据,确认最终需要替换回原集合的 id 及对应 Key 列表,同时将不需要的记录过滤掉。
查看闪回集合中的数据,确认是否符合按 Key 筛选条件,是否符合回到目标时间点 B 的数据要求,并选出需替换回原集合的数据记录。如下图所示,闪回集合里的2条数据都符合时间点 B 的要求。

步骤3:根据选出的 Key 列表,匹配的文档,将文档按照 id 及对应的 Key 通过 upsert 方式写回原集合。
1. 使用
forEach 命令将闪回集合test_bak1016151413中 _id 对应文档更新到原集合test中。db.test_bak1016151413.find({ _id: { $in: [ObjectId("652d2a6505726f70625ce5cf"), ObjectId("652d2a6b05726f70625ce5d0")] } }).forEach(function (doc) {db.test.updateOne({ _id: doc._id }, { $set: doc }, { upsert: true });});
2. 查看原集合内数据符合预期。如下图所示,张三和李四的数据已更新回时间点 B 的状态,符合预期。

步骤4:如有缺失记录集合,按业务需求决定是否将原集合的对应记录删除。
若有缺失记录集合,说明目标时间点还没有该集合中的对应 id 的数据,根据情况考虑是否将原集合中对应 id 数据进行删除。如下图所示,赵六的数据在时间点B 并不存在,如果判断需要清理该数据,则执行数据删除操作。

删除后,查看原集合内数据符合预期。
