在数据库运维过程中,如果运维不规范,未建立容灾环境并未制定合适的备份策略并备份,在某些极端情况下(比如主机异常断电),可能导致数据库实例无法启动。此时,怎么尽最大的可能拯救数据?

在Oracle中,提供了一些隐含参数或者方法让数据库强制启动,并在捞出数据后重建数据库,或者利用DUL等工具尽可能的进行数据提取。那么在mongodb数据库的运维过程中,遭遇数据库文件损坏,实例无法启动的时候怎么办?我们都知道Mongodb从3.2版开始,默认使用的wiredTiger开源存储引擎,通过在github上下载wt引擎的源码,可以编译生成一个wt工具,利用该工具可以从mongodb数据文件中捞出数据。


[ 数据恢复 ]

工具安装

软件下载地址:https://github.com/wiredtiger/wiredtiger,安装方法:

  1. 安装依赖包

yum-y install snappy.x86_64 snappy-devel.x86_64

  1. 编译安装

./configure--enable-snappy –prefix=/usr/local/wiredTiger

make&&makeinstall

数据恢复

在mongodb数据目录的文件结构中,包括数据库文件和WiredTiger.wt等元数据文件,若元数据文件丢失,则会导致wt工具也无法恢复数据,出现类似如下报错:

[1600001107:222670][28965:0x7f7a4a987740],file:WiredTiger.wt, connection: __posix_open_file, 715:/data/mongodb/WiredTiger.wt: handle-open: open: No such file ordirectory

mongodb的瓶颈 mongodb数据量瓶颈_mongodb

如上图所示,需保证红框外的文件都在,才能从数据文件中抓取数据。

wt -v -h /data/mongodb -C"extensions=[/usr/local/wiredtiger/lib/libwiredtiger_snappy.so]"list –列出所有的对象名称,由于WT引擎默认使用了snappy压缩算法,所以需要使用extensions显示指定类文件位置。

mongodb的瓶颈 mongodb数据量瓶颈_数据_02

从数据文件中导出数据:

/usr/local/wiredtiger/bin/wt -v -h /data/mongodb -C"extensions=[/usr/local/wiredtiger/lib/libwiredtiger_snappy.so]" dump -f /home/mongo/a.dmp test/collection/7-6614138329248103296

导出的文件在此时不是json文件,不能直接读取,需导入一个临时数据库中

>show dbs;

admin  0.000GB

config 0.000GB

local  0.000GB

>use test

>db.createCollection("test");

{"ok" : 1 }

>show tables;

test

>db.test.stats().wiredTiger.uri;

statistics:table:test/collection/0--2648066414802528487  --获取临时集合的数据文件信息

[mongo@node1~]$ mongod -f /etc/mongodb/mongodb1.conf ---shutdown##停止临时数据库,否则在导入的时候会报资源忙

[1600004969:259849][25396:0x7f9657853740],wiredtiger_open: __posix_file_lock, 410:/data/mongodb1/WiredTiger.lock: handle-lock: fcntl: Resourcetemporarily unavailable

[1600004969:259905][25396:0x7f9657853740],wiredtiger_open: __conn_single, 1720: WiredTiger database is alreadybeing managed by another process: Device or resource busy

数据导入:

[mongo@node1~]$  /usr/local/wiredtiger/bin/wt  -v -h /data/mongodb1 -C"extensions=[/usr/local/wiredtiger/lib/libwiredtiger_snappy.so]"-R load -f /home/mongo/a.dmp  -rtest/collection/0--2648066414802528487

file:test/collection/0--2648066414802528487:100002  --提示导入了100002个document

启动数据库,但是我们发现此时导入的数据可以find,但是count为0,如下图:

mongodb的瓶颈 mongodb数据量瓶颈_mongodb_03

此时,我们采用导出和导入的方法更新元数据

mongodb的瓶颈 mongodb数据量瓶颈_数据库_04

再次查询,集合文档数据量count可正常显示,见下图:

mongodb的瓶颈 mongodb数据量瓶颈_mongodb数据量太大count超时_05

注:wt工具导出和导入数据只能按集合逐一进行,mongodump和mongorestore修复元数据,可以按库多个集合同时修正。


[ 总结 ]

本文档使用的案例是在测试环境的测试案例。本文仅仅是提供一种在极端情况下尽可能救援数据的一种方法,但使用过程中也有诸多限制。本人认为,成熟的运维应该是制定完善的运维方案,建立合适的数据库备份策略和数据库容灾架构,不到万不得已,不使用此类非常规的手段恢复数据。