使用 WT 工具恢复 MongoDB 数据
众所周知 MongoDB 的底层存储是由 WiredTiger 负责的,其数据文件也是.wt 格式。既然如此,我们就有可能不通过 MongoDB 服务,而是直接用 wt 工具从数据文件中恢复数据。虽然我们通常推荐生产环境一定要配置复制集,但是很无奈,技术社区已经数次有人因为单机运行,最后硬盘损坏等原因导致无法启动。wt 工具作为最后一根稻草,可以在放弃治疗前再尝试挽救一下。
编译
wt 工具可以运行于 Linux 和 Windows 上。因为各自的操作系统和 MongoDB 版本不同,可能产生较多的组合。在使用时应该根据自己情况编译适合的版本。下面以 CentOS 7 为例演示编译过程。
1.安装操作系统依赖
2. 准备源码
根据所使用的 MongoDB 版本,应该选择正确的 wt 分支。例如我当前使用的 MongoDB 4.4.1,那么同样应该选择 WiredTiger 的相应 tagmongodb-4.4.1
编译源码
简单起见我们使用了--disable-shared 来将动态链接库直接打包到执行文件中,这样可以避免很多后续的麻烦,代价是生成的执行文件较大。
编辑数据
如果有幸 dbpath 中的其他文件没有丢失,包括:
WiredTiger*
要恢复的集合的 collection-xxx.wt
与要恢复集合相关的 index 文件
则可以直接使用 wt 工具恢复数据了:
wt dump file:collection-10--2280053313118266952.wt
不过,如果所有东西都还在的话,为什么还要用 wt 来恢复呢?所以我相信大部分人到这里都是跑不下去的。所以来看下一步,当你丢到只剩个裤衩子的时候该怎么办。
数据恢复
wt 读取数据的基本前提条件是要有元数据,也就是 WiredTiger*那堆文件。那我们就来尝试构造这些文件:
mkdir tempcd temptouch WiredTiger WiredTiger.lockwt list
为了简单起见,后续步骤我们没有使用 wt 来完成,而是使用 MongoDB:
mongod --dbpath ./
启动另一个窗口,使用 mongo shell 连接到当前实例:
mongo
任意创建一个集合,我们将把数据恢复到这个集合中:
collection-7-666354062479792805.wt 即我们要使用的目标文件名。此时应:
停止 mongod(直接 ctrl-c)
使用我们要恢复的文件覆盖上述文件
cp collection-10--2280053313118266952.wt collection-7-666354062479792805.wt
让 wt 帮我们修复文件:
wt salvage file:collection-7-666354062479792805.wt
重启 mongod 进程:
mongod --dbpath ./
再次使用 shell 连接到 MongoDB,在 dump 集合中即可找到我们要恢复的数据。
注意此时集合数据虽然恢复正常,但如果你 count()就会发现返回结果是 1。不用担心,这个问题很容易修复:
db.dump.validate({full: true});
下面该怎么办大家心里有数了吗?
关于作者:张耀星
MongoDB 大中华区首席咨询顾问,供职于 MongoDB 售后服务团队 5 年+,拥有近 10 年 MongoDB 使用经验。
评论