首页 技术 正文
技术 2022年11月11日
0 收藏 899 点赞 4,093 浏览 2214 个字

WiredTiger.wt文件是mongoDB的元数据文件,存储了其他数据库表的元数据信息。笔者最近遇到了WiredTiger.wt文件损坏的情况,MongoDB无法启动,数据库中的重要数据危在旦夕…

一、网上大多数文章的恢复方案 – 使用wt工具对数据进行打捞

由于笔者之前没有接触过MongoDB,对其知之甚少,只能参考网上的文章来试图恢复数据。看了下网上的文章,大多是说通过wt工具来打捞数据。然而wt工具打捞数据,需要WiredTiger.wt文件是完好可用,并不适用于笔者遇到的情形。

二、源码面前,了无秘密 – 读源码,直接从wt数据文件恢复数据

网上的恢复方案不对症,无奈只能另寻他法。

通过阅读wiredtiger的代码发现,wt数据文件中,数据库记录以bson格式存储的,并默认通过snappy进行了压缩,数据默认没有进行加密

1. wt数据文件结构分析

使用vim的十六进制模式观察collection*.wt数据文件发现:

  • wt数据文件的前4096字节是该wt文件的元数据信息
  • wt数据文件从4096开始存储数据库记录
  • wt数据文件的记录对齐4096

把视线聚焦到单独的某个记录上:

0001000: 0000 0000 0000 0000 0100 0000 0000 0000  ................
0001010: 70e2 0000 0200 0000 0705 0000 0060 0000 p............`..
0001020: fa49 5207 0100 0000 0581 80e2 c1c2 42e2 .IR...........B.
0001030: 0000 105f 6964 0057 0000 0010 7573 6572 ..._id.W....user
0001040: 9454 0000 0000 0000 b0c4 0330 5f69 6400 .T.........0_id.
0001050: e6a2 675c 1074 6173 6b01 0df0 4402 0000 ..g\.task...D...
0001060: 0002 696d 6167 655f 6e61 6d65 002f 0000 ..image_name./..
0001070: 006c 796d 7068 5f6e 6f64 655f 6d69 6372 .lymph_node_micr
0001080: 6f73 636f 7065 5753 495f 3139 3032 3238 oscopeWSI_190228
0001090: 5f31 3930 3330 3839 3231 312e 7376 7300 _1903089211.svs.
00010a0: 1069 053f e869 6400 7f09 0000 026a 736f .i.?.id......jso

在wiredtiger源码中定义每个数据数记录的存储格式:

  • 00 – 07 字节,recno,记录编号,关系不大
  • 00 – 15 字节,write_generation
  • 16 – 19 字节,记录解压后的size(记录默认是通过snappy压缩的),用于解压
  • 28 – 31 字节,在源码没找到,但是通过观察,应该是该记录的存储size,对齐4096,用于记录读取
2. 记录读取及snappy解压

从记录头部读取头部64字节的数据,从而解析到:

  • 记录解压后size,后文称 decompress_size
  • 记录存储size,后文称 store_size

从记录开头读取 store_size 字节的数据,跳过WT_BLOCK_COMPRESS_SKIP字节,对其后数据进行snappy解压,解压后数据总大小应为 decompress_size 。

3. 从记录中提取bson格式的数据

记录解压后,前面的很多字节并不是bson的数据,笔者也没详细去看前面的字节到底是什么,而是通过一个巧办法暴力地提取了bson格式的数据。

bson格式的前4个字节是bson数据的size,后面的数据会以 类型、名称、值这样的形式存储,具体可参考网上关于bson格式解释的文章

0001000: 0000 0000 0000 0000 0100 0000 0000 0000  ................
0001010: 70e2 0000 0200 0000 0705 0000 0060 0000 p............`..
0001020: fa49 5207 0100 0000 0581 80e2 c1c2 42e2 .IR...........B.
0001030: 0000 105f 6964 0057 0000 0010 7573 6572 ..._id.W....user

数据库记录中有个 _id 这样的字段、该字段的类型为32位数值,在bson中该类型表示为 0x10,因此这个32位数值类型的_id,会存储为105f 6964。其中,10是类型,5f 6964是_id,其后的32位存储了它的实际数值。
由于_id是bson数据中的第一个字段,根据bson格式定义,105f 6964前面的4个字节 42e2 0000是bson数据的大小,也就是bson数据的起始位置。

通过该寻找105f 6964,可以定位到bson数据的起始位置,并将bson数据存储成bson文件,如xxx.bson

4. 使用bsondump来解析bson文件,得到数据
[root@h-100 ~]# bsondump xxx.bson

三、切记、切记

使用MongoDB时,像WiredTiger.wt这样重要并不大的文件,多做备份,避免不必要的麻烦

五、关注笔者

专注笔者公众号,阅读更多干货文章:)

最牛MongoDB灾难恢复(WiredTiger.wt文件损坏,Mongo无法启动)

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,951
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,477
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,290
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,107
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,739
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,773