原文链接
译文链接,我看的这篇,因为没有给出来原文链接,所以刚开始没找到原文
背景
数据文件是wt文件,而且是通过
snappy
方式压缩的,如果不是通过snappy
方式,也可以参考下这个方式,不过执行命令可能有所不同
这个解决方案非常适合这样的场景:服务器意外故障(例如断电),突然停机,导致mongodb数据文件损坏,进而导致了mongod
进程无法启动
但是我却是遇到了这样的问题:服务器由于磁盘空间占用达到100%导致mongod
进程挂掉,由于磁盘100%,无法再启动mongo进程,所以工作人员直接删掉了部分的wt文件,释放部分磁盘空间,然后再次启动mongo的时候,发现无法启动了。。。
无法启动的原因是mongo启动的时候会做一次检测,检查mongodb的数据文件和某个地方存储的信息是否一致的(具体这个位置我们暂时还不清楚),如果不一致,将会无法启动mongo进程。进程无法启动导致了很多严重的问题,好在这个数据库记录的都是一些非业务信息,数据的查询更新操作也不算太多,为了让集群快速可用,我们直接更改了一个空的数据目录,启动mongod
进程,让集群先可用
然后问题来了,原来的数据要怎么恢复呢?于是我们就有了从wt文件中抽取出数据的需求,所以就有了以下过程
恢复过程
准备工具
1 | yum install -y snappy |
准备恢复目录mongo-bak
目录包含以下内容1
2
3
4
5
6
7
8
9collection********.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 | mongo |
创建完成之后,就能看到刚刚新建的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 | mongo |
count
是无法查到数据的,还是需要find
1 | db.brokedCollection.find({}, {_id: 1}) |
将数据dump出来,然后重新写进去
mongodump
mongorestore
注意,这里的
mongodump
和mongorestore
都要使用3.2版本的
数据经过导入导出之后就可以count
出来了
思考
以上恢复过程是针对数据库文件被直接删掉的情况。假如说当前数据库启动无误,这时候一个误删,删掉了数据库文件应该如何处理呢?
使用lsof恢复误删的文件
这边文章写的清楚如何进行文件恢复