使用wt工具恢复mongo数据库单个集合文件

发布时间 2023-07-20 16:18:31作者: 柴米油盐酱醋

单节点 MongoDB,宕机后 --repair 起不来,或只有 collection 物理文件想做数据恢复,使用 wt 工具恢复方法。

参考文档:
https://mongoing.com/archives/81301
https://blog.csdn.net/qq_28018283/article/details/106658647
https://nintha.github.io/2018/05/06/MongoDB/Wiredtiger_restore_MongoDB_data/
https://developer.aliyun.com/article/73203
https://www.alexbevi.com/blog/2016/02/10/recovering-a-wiredtiger-collection-from-a-corrupt-mongodb-installation/?spm=a2c6h.12873639.article-detail.4.36963e4akPZdRG
https://source.wiredtiger.com/11.1.0/build-posix.html


本地环境:
arm ubuntu 20

1、安装依赖包

apt-get install libsnappy-dev build-essential

2、安装 wt 工具

参考:https://source.wiredtiger.com/11.1.0/build-posix.html

其中【git clone git://github.com/wiredtiger/wiredtiger.git】替换为【git clone https://github.com/wiredtiger/wiredtiger.git】
cmake 时会报一些 not found 的错误,是缺少依赖包,反馈 chatpgt 安装好依赖就能正常安装了。
按照文档操作到 make install 即可。

3、执行 wt 工具

第一次执行 wt 命令报错【/usr/local/bin/wt: error while loading shared libraries: libwiredtiger.so.11.2.0: cannot open shared object file: No such file or directory】

解决方法:【export LD_LIBRARY_PATH=/usr/local/lib/libwiredtiger.so.11.2.0:$LD_LIBRARY_PATH】

4、恢复单个物理文件

整个恢复流程基本参考张耀星的这篇文章【https://mongoing.com/archives/81301】
基本思路就是创建一个没用的集合,找到没用集合对应的物理文件,将要恢复的物理文件替换掉没用集合的物理文件。
比如目前有一个集合的物理文件要恢复【文件名称:collection-11-1234567890.wt】



恢复流程:

4.1 启动一个mongo实例
mongod --dbpath "/root/tmpdata1"  --port 27018
4.2 进入数据库创建空集合,记录 uri 信息中的文件名称 collection-8--7050449506244367834 ,它是 t1 集合对应的物理文件名称。
mongo --port 27018

> show dbs
admin   0.000GB
ceshi   0.004GB
config  0.000GB
local   0.000GB
> use ceshi
switched to db ceshi
> db.t1.insert({id:1})
WriteResult({ "nInserted" : 1 })
> show tables
t1

> db.t1.stats()
{
        "ns" : "ceshi.t1",
        "size" : 6301010,
        "count" : 10589,
        "avgObjSize" : 595,
        "storageSize" : 3411968,
        "capped" : false,
        "wiredTiger" : {
                "metadata" : {
                        "formatVersion" : 1
                },
                "creationString" : "",
                "type" : "file",
                "uri" : "statistics:table:collection-8--7050449506244367834",

4.3 关闭数据库替换物理文件

关闭数据库后,开始替换物理文件
root@db-0:~/tmpdata1# ll
total 4212
drwxr-xr-x  4 root root    4096 Jul 20 15:59 ./
drwx------ 19 root root    4096 Jul 20 14:27 ../
-rw-------  1 root root      46 Jul 20 14:27 WiredTiger
-rw-------  1 root root      21 Jul 20 14:27 WiredTiger.lock
-rw-------  1 root root    1254 Jul 20 15:59 WiredTiger.turtle
-rw-------  1 root root   49152 Jul 20 15:59 WiredTiger.wt
-rw-------  1 root root   49152 Jul 20 15:56 WiredTiger.wt.orig
-rw-------  1 root root    4096 Jul 20 15:59 WiredTigerLAS.wt
-rw-------  1 root root   36864 Jul 20 15:59 _mdb_catalog.wt
-rw-------  1 root root   20480 Jul 20 15:59 collection-0--7050449506244367834.wt
-rw-------  1 root root   36864 Jul 20 15:59 collection-2--7050449506244367834.wt
-rw-------  1 root root   36864 Jul 20 15:59 collection-4--7050449506244367834.wt
-rw-r--r--  1 root root 3411968 Jul 20 15:59 collection-8--7050449506244367834.wt  --这个文件
drwx------  2 root root    4096 Jul 20 15:59 diagnostic.data/
-rw-------  1 root root   36864 Jul 20 15:59 index-0-8916583402311889064.wt
-rw-------  1 root root  487424 Jul 20 15:59 index-1-8916583402311889064.wt
-rw-------  1 root root   24576 Jul 20 15:59 index-2-8916583402311889064.wt
-rw-------  1 root root   24576 Jul 20 15:59 index-3-8916583402311889064.wt
-rw-------  1 root root   20480 Jul 20 15:59 index-4-8916583402311889064.wt
drwx------  2 root root    4096 Jul 20 15:56 journal/
-rw-------  1 root root       0 Jul 20 15:59 mongod.lock
-rw-------  1 root root   36864 Jul 20 15:59 sizeStorer.wt
-rw-------  1 root root     114 Jul 20 14:27 storage.bson
root@db-0:~/tmpdata1# rm -rf collection-8--7050449506244367834.wt
root@db-0:~/tmpdata1# cp /tmp/collection-11-1234567890.wt collection-8--7050449506244367834.wt

4.4 修复文件,并启动数据库

#注意:wt 命令一定要在mongo数据目录中执行
root@db-0:~/tmpdata1# /usr/local/bin/wt -v -C "extensions=[/usr/local/lib/libwiredtiger_snappy.so]"  salvage file:collection-8--7050449506244367834.wt
        WT_SESSION.salvage 100                 
root@db-0:~/tmpdata1# 

#正常启动数据库
root@db-0:~/tmpdata1# mongod --dbpath "/root/tmpdata1"  --port 27018
报错:
2023-07-20T16:04:56.754+0800 F  STORAGE  [initandlisten] Please read the documentation for starting MongoDB with --repair here: http://dochub.mongodb.org/core/repair
2023-07-20T16:04:56.754+0800 F  -        [initandlisten] Fatal Assertion 50944 at src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp 922
2023-07-20T16:04:56.754+0800 F  -        [initandlisten] \n\n***aborting after fassert() failure\n\n

#使用 --repair 修复一下数据库,修复完成后会自动关闭数据库
root@db-0:~/tmpdata1# mongod --dbpath "/root/tmpdata1"  --port 27018  --repair

#再次正常启动数据库,成功
root@db-0:~/tmpdata1# mongod --dbpath "/root/tmpdata1"  --port 27018
2023-07-20T16:07:00.336+0800 I  NETWORK  [listener] Listening on /tmp/mongodb-27018.sock
2023-07-20T16:07:00.336+0800 I  NETWORK  [listener] Listening on 127.0.0.1
2023-07-20T16:07:00.336+0800 I  NETWORK  [listener] waiting for connections on port 27018

4.5 查询数据

> show dbs
admin   0.000GB
ceshi   0.004GB
config  0.000GB
local   0.000GB
> use ceshi
switched to db ceshi
> db.t1.count()
589
>  db.t1.find().limit(1)
{ "_id" : "xxx", "userId" : 123}
> 

我本地是 MongoDB 4.2环境,发现恢复 MongoDB 6.0 环境的物理文件也是可以的。