Mongodb的Wiretiger.turtle丢失后的数据恢复

环境信息

Mongodb版本:3.2.17
操作系统:centos 7.0.1406

问题表现

  • 日志内打印 chown: cannot access '/data/db/WiredTiger.turtle':No such file or directory无法启动Mongodb

  • 查看Mongodb数据目录,发现存在Wiretiger.turtle,ll命令查看,该文件所属用户,所属组,时间,权限信息等皆为问号

原因分析

猜测由于断电原因导致WiredTiger.turtle文件损坏,其中WireTiger为Mongodb所使用的默认存储引擎,WireTiger.wt文件为存储引擎的元数据,而WireTiger.turtle文件是WireTiger.wt文件的元数据[1][2].查阅资料未发现可直接修复该文件的办法[3],进行过测试,用 WT工具修复mongodb数据并不适用于Wiretiger.turtle文件丢失的情况[4][5][6][7].

修复思路

在mongodb,会将建立的collection信息写入数据目录下名称类似collection-14--6455635868234258390.wt的文件中,利用4.x版本的Mongodb更好的数据修复能力,将需要恢复的collection-xxx-wt文件替换4.x版本的collection-xxx-wt,运行mongodb --repair指令,进行数据恢复4,数据恢复出来后会丢失原来的库名与表名,需要自己通过恢复的内容判断原先的库名与表名

修复步骤

安装4.x版本Mongo和mongo工具

打开https://www.mongodb.com/try/download/database-tools?tck=docs_databasetools

  • 下载并安装4.x版本的mongodb
  • 下载并安装mongodb工具databasetools(为了使用mongodump与mongoretore工具将数据从mongodb4.x复制回我当前的3.x的mongodb)

在4.x版本Mongo中新建colleciton及插入数据,查询该collection的文件路径

此处我创建了数据库test,并创建了集合cola,并通过stat命令查询到集合的文件路径

db.cola.insert({"a":"b"});//新建colleciton及插入数据(插入时如果cola不存在,mongo会自动给创建)
db.cola.stats();//可以通过给命令查询该集合存储的文件名

如下,查询结果中wiredTiger.uri的值“statistics:table:collection-120--8692011111779330506”中的collection-120--8692011111779330506即为存储该集合cola的文件名

{
    "ns" : "test.colb",
    "count" : 2679549,
    "size" : 2448341002,
    "avgObjSize" : 913,
    "storageSize" : 580358144,
    "capped" : false,
    "wiredTiger" : {
        "metadata" : {
            "formatVersion" : 1
        },
        "creationString" : "",
        "type" : "file",
        "uri" : "statistics:table:collection-120--8692011111779330506"
}

关闭4.x版本mongo,将原来的collection--xxx.wt覆盖上一步查询到的collection-xxx.wt文件

执行repair

由于我启动的mongodb以mongod运行,所以我也以mongod用户运行repair命令

su mongod -c "mongod --dbpath /var/lib/mongo --repair"

启动mongodb,查询cola,检查丢失的数据是否恢复

启动4.x版本mongodb(或者其他启动方式)

service mongod start

查询cala的数据,如果出现需要恢复的数据,并且数量没有问题,说明恢复成功

db.cola.find()

最后的处理

可以通过mongo提供的工具mongodump,mongoexport,mongoretore,mongoimport将恢复的数据从4.x版本mongodb导入到原来的旧版本数据库,至此数据恢复完成

我的处理步骤,也可以自行通过mongoexport与mongoimport配合进行恢复:

  1. 通过mongodump命令与mongoretore命令将数据导回到3.x的mongodb中的test库内

    导出

    mongodump -h 4.x数据库ip -d 需要备份的数据库名 -o 备份的路径
    

    导入

    mongorestore -h 3.x数据库ip -d 3.x数据库名 备份的数据
    
  2. 运行下述mongodb命令,将每个表恢复回原来的数据库的表内,例如下面是将表cola恢复会原来的audio库中的file表

    var count=0;
    var ops=[];
    var dbase="audio";//原来的数据库名
    var col="file";//原来的表名
    var colbak="cola";//数据临时存储的表名
    db.colbak.find({}).forEach(function(e){
        ops.push({insertOne  : { "document" : e}});
        count++;
        if(count>0&&count%1000==0) {
            db.getSiblingDB(dbase).col.bulkWrite(ops,{ordered:false});
            ops = [];
            print("更新条数:" + count);
        }
    });
    if(ops.length > 0){
        db.getSiblingDB(dbase).col.bulkWrite(ops, {ordered:false});
    }
    print("更新条数:" + count);
    

其他问题

  1. 是否能直接删除Wiretiger.turtle文件,再运行mongo --repair进行修复

    • 答:不能,在我手上环境里的3.x和4.x版本的mongodb上测试过,无论是运行mongo --repaire,还是直接重启mongo,mongo都会新建Wiretiger.turtle,查看日志打印如下信息:

      unexpected file WiredTiger.wt found, renamed to WiredTiger.wt.1
      

      可能多次重启mongodb都无法启动,即使mongodb能启动起来,查看mongodb,看到的将是一个空的mongodb数据库

  2. 是否Mongodb 4.x版本,5.x版本可以运行mongo --repaire进行修复

    • 答:还未测试过
  3. 运行mongo --repair 后,启动mongo提示permission denied类似的错误

    • 答:可能是运行mongo --repair 与启动mongodb服务的用户不是同一个用户,可以同过ll命令查看下mongodb的数据目录下这些文件的所属用户与权限,如果不一样例如Wiredtiger.turtle文件的所属用户为root,而其他文件的所属用户为mongodb,则应该是该问题,对权限做下处理,例如运行mongo --repair命令时保持与启动mongodb的用户为同一个用户或者直接对数据目录赋予755权限
  4. 修复一个2g多的collection-xxx.wt文件,运行mongo --repair 后,没有打印明显修复某某数据的信息,并且很快就关闭了,启动mongo提示报错(不是permission denied类似的错误)

    • 答: 我也曾经出现过这个情况,关闭mongodb数据库,把数据命令删除,把修复过程重新执行多几遍
  5. 能否修复索引信息

    • 答:未试过,可自行尝试.

参考资料


  1. [1] WiredTiger Metadata

  2. [2] MongoDB 存储引擎Wiredtiger原理剖析

  3. [3] SERVER-37322

  4. [4] Repairing MongoDB When WiredTiger.wt File is Corrupted

  5. [5] Recovering a WiredTiger collection from a corrupt MongoDB installation

  6. [6] 从损坏的wt文件中恢复出WiredTiger集合

  7. [7] MongoDB 无法启动,WiredTiger 如何恢复数据(二)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容