Kivi

没有什么远大理想,只是永远都不会满足而已


  • 首页

  • 关于

  • 标签

  • 归档

mongodb wt数据文件损坏解决方案

发表于 2017-07-08 更新于 2017-07-10 分类于 mongodb 阅读次数:
本文字数: 2.1k 阅读时长 ≈ 2 分钟

原文链接
译文链接,我看的这篇,因为没有给出来原文链接,所以刚开始没找到原文

背景

数据文件是wt文件,而且是通过snappy方式压缩的,如果不是通过snappy方式,也可以参考下这个方式,不过执行命令可能有所不同

这个解决方案非常适合这样的场景:服务器意外故障(例如断电),突然停机,导致mongodb数据文件损坏,进而导致了mongod进程无法启动

但是我却是遇到了这样的问题:服务器由于磁盘空间占用达到100%导致mongod进程挂掉,由于磁盘100%,无法再启动mongo进程,所以工作人员直接删掉了部分的wt文件,释放部分磁盘空间,然后再次启动mongo的时候,发现无法启动了。。。

无法启动的原因是mongo启动的时候会做一次检测,检查mongodb的数据文件和某个地方存储的信息是否一致的(具体这个位置我们暂时还不清楚),如果不一致,将会无法启动mongo进程。进程无法启动导致了很多严重的问题,好在这个数据库记录的都是一些非业务信息,数据的查询更新操作也不算太多,为了让集群快速可用,我们直接更改了一个空的数据目录,启动mongod进程,让集群先可用

然后问题来了,原来的数据要怎么恢复呢?于是我们就有了从wt文件中抽取出数据的需求,所以就有了以下过程

恢复过程

准备工具

最新下载页面

1
2
3
4
yum install -y snappy
wget http://source.wiredtiger.com/releases/wiredtiger-2.9.3.tar.bz2
# 解压,进入目录
./configure --enable-snappy

准备恢复目录mongo-bak

目录包含以下内容

1
2
3
4
5
6
7
8
9
collection********.wt
_mdb_catalog.wt
sizeStorer.wt
storage.bson
WiredTiger
WiredTiger.basecfg
WiredTiger.lock
WiredTiger.turtle
WiredTiger.wt

数据文件修复(我没做这一步处理因为没有必要)

打捞出可以修复的部分

注意仍在wt下载目录下执行

1
./wt -v -h ../mongo-bak -C "extensions=[./ext/compressors/snappy/.libs/libwiredtiger_snappy.so]" -R salvage collection******.wt

数据格式调整

1
./wt -v -h ../mongo-bak -C "extensions=[./ext/compressors/snappy/.libs/libwiredtiger_snappy.so]" -R dump -f ../collection.dump collection******

注意,这个命令的最后一个参数是不带.wt的

这样就把刚才修复的数据写到collection.dump中了

在目标mongodb中创建一个集合(数据将会被恢复到这个mongodb中)

1
2
3
4
5
mongo
> use Recovery
> db.brokedCollection.insert({test: 1})
> db.brokedCollection.remove({})
> db.brokedCollection.stats()

创建完成之后,就能看到刚刚新建的wt文件了,假设记为xxx.wt

将collection.dump的数据写入xxx.wt

1
./wt -v -h ../tmp-mongo -C "extensions=[./ext/compressors/snappy/.libs/libwiredtiger_snappy.so]" -R load -f ../collection.dump -r xxx

注意,这里最后一个参数也是不带wt的。另外执行这一步的时候,必须要先关闭掉mongo进程,否则会提示wt文件被占用,无法写入数据

查看已经被恢复的数据

将mongo进程启动之后,建议使用3.2的mongo客户端链接

1
2
3
4
5
mongo
> show dbs
> use Recovery
> show collections
> db.brokedCollection.count()

count是无法查到数据的,还是需要find

1
> db.brokedCollection.find({}, {_id: 1})

将数据dump出来,然后重新写进去

mongodump

mongorestore

注意,这里的mongodump和mongorestore都要使用3.2版本的

数据经过导入导出之后就可以count出来了

思考

以上恢复过程是针对数据库文件被直接删掉的情况。假如说当前数据库启动无误,这时候一个误删,删掉了数据库文件应该如何处理呢?

使用lsof恢复误删的文件
这边文章写的清楚如何进行文件恢复

# mongodb
天云山·北京平谷
mongodb生产部署建议
  • 文章目录
  • 站点概览
kivi

kivi

nodejs | server
58 日志
17 分类
32 标签
RSS
  1. 1. 背景
  2. 2. 恢复过程
    1. 2.1. 准备工具
    2. 2.2. 准备恢复目录mongo-bak
    3. 2.3. 数据文件修复(我没做这一步处理因为没有必要)
    4. 2.4. 数据格式调整
    5. 2.5. 在目标mongodb中创建一个集合(数据将会被恢复到这个mongodb中)
    6. 2.6. 将collection.dump的数据写入xxx.wt
    7. 2.7. 查看已经被恢复的数据
    8. 2.8. 将数据dump出来,然后重新写进去
  3. 3. 思考
© 2019 kivi | 173k | 2:37
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0
|