注册

MongoDB利用oplog恢复数据的方法

当 MongoDB 的主服务器发生故障时,管理员可以利用副本集中的数据、oplog 和其他工具来恢复数据。下面是利用 oplog 恢复数据的方法:

1. 确定恢复点

首先需要确定故障发生的时刻,也就是需要恢复到的时间点。可以通过查询主节点的 oplog 来确定时间点。使用以下命令查找 oplog 中的最后一个条目:

db.oplog.rs.find().sort({$natural:-1}).limit(1)

可以看到该命令返回了一个 JSON 对象,其中 ts 字段对应的时间即为最后一个 oplog 条目的时间戳。

确定时间点后,需要记录下来,并保证不能在此时间点之后继续写入数据。

2. 关闭 MongoDB

在进行数据恢复之前,必须先关闭 MongoDB,以确保数据一致性。

3. 备份数据

进行任何数据恢复操作前,务必进行完备份。

4. 启动 MongoDB

在确认已关闭 MongoDB 并备份了数据后,可以启动 MongoDB 并进入副本集的第二节点(即 Secondary 节点)。

5. 过滤 oplog 条目

进入 Secondary 节点后,需要将 oplog 中的条目按照时间过滤,只保留需要恢复的时间点之前的条目。可以使用以下命令:

use local
var ts = new Timestamp(1620989259, 1)
db.oplog.rs.find({ts:{$lte:ts}})

其中 ts 字段需要替换为实际需要恢复到的时间点。

6. 初步恢复数据

过滤出符合要求的 oplog 条目后,可以使用 mongorestore 来恢复数据。需要指定 --oplogReplay 参数以恢复 oplog,如下所示:

mongorestore --oplogReplay --gzip --dir=

其中 指代备份文件的目录,需要根据实际情况替换。

7. 检查数据

完成初步恢复后,需要检查数据是否已经成功恢复。可以在 Secondary 节点上执行以下命令:

db.runCommand({checkShardingIndex: "collection_name"})

其中 collection_name 字段需要替换为实际需要检查的集合名称。

8. 启动主服务器

经过检查确认数据恢复成功后,可以再次启动主服务器并将其加入副本集中。此时,主服务器上缺少的数据会从副本集中的其他数据节点复制回来。

示例1:

假设我们的 MongoDB 集群中的 Primary 节点出现了连接问题,需要将 Secondary 节点提升为 Primary 节点。具体步骤如下:

  1. 关闭 Primary 节点上的 MongoDB。

  2. 在 Secondary 节点上使用 rs.status() 命令检查副本集状态,确认该节点已成为 Secondary 节点。

  3. 在 Secondary 节点上使用 rs.stepDown() 命令将其从 Secondary 节点转换为 Primary 节点。

  4. 重新启动 Primary 节点上的 MongoDB,并将其添加到副本集中。

示例2:

假设我们需要删除某个集合中的所有文档,但是误删了其中一些数据,需要通过 oplog 进行恢复。具体步骤如下:

  1. 在删除文档之前,需要备份整个数据库,以便出现意外时可以进行数据恢复。

  2. 确定需要恢复的时间点,并过滤出该时间点之前的 oplog 条目。

  3. 使用 mongorestore 进行初步恢复。

  4. 在 Secondary 节点上执行 db.checkpoint() 命令创建新的 checkpoint。(该步骤只适用于 MongoDB 3.4 及之前的版本,3.6 及之后的版本不需要执行该命令)

  5. 检查数据是否恢复成功。

  6. 启动 Primary 节点上的 MongoDB,并将其添加到副本集中。