MongoDB无法启动,如何恢复数据?

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: 近日有 MongoDB 用户遇到一个问题,使用 Wiredtiger 存储引擎的 MongoDB 无法启动,咨询我数据能否恢复回来,能恢复多少是多少 ... 问题出现的场景据用户描述是「mongod磁盘写满了,导致进程 crash」,尝试重新启动,结果 wiredtiger 报错,错误信息类似如下,类似的问题 mongodb jira 上也有人提过,可以参考 SERVER-26924,说明此时 MongoDB 数据文件已经损坏。

近日有 MongoDB 用户遇到一个问题,使用 Wiredtiger 存储引擎的 MongoDB 无法启动,咨询我数据能否恢复回来,能恢复多少是多少 ...

问题出现的场景据用户描述是「mongod磁盘写满了,导致进程 crash」,尝试重新启动,结果 wiredtiger 报错,错误信息类似如下,类似的问题 mongodb jira 上也有人提过,可以参考 SERVER-26924,说明此时 MongoDB 数据文件已经损坏。

2017-03-28T22:06:05.315-0500 W -        [initandlisten] Detected unclean shutdown - /data/mongodb/mongod.lock is not empty.
2017-03-28T22:06:05.315-0500 W STORAGE  [initandlisten] Recovering data from the last clean checkpoint.
2017-03-28T22:06:05.324-0500 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=13G,session_max=20000,eviction=(threads_max=4),statistics=(fast),log=(enabled=true,archive=true
,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2017-03-28T22:06:05.725-0500 E STORAGE  [initandlisten] WiredTiger (0) [1454119565:724960][1745:0x7f2ac9534bc0], file:WiredTiger.wt, cursor.next: read checksum error for 4096B block at offset 6
799360: block header checksum of 1769173605 doesn't match expected checksum of 4176084783
2017-03-28T22:06:05.725-0500 E STORAGE  [initandlisten] WiredTiger (0) [1454119565:725067][1745:0x7f2ac9534bc0], file:WiredTiger.wt, cursor.next: WiredTiger.wt: encountered an illegal file form
at or internal value
2017-03-28T22:06:05.725-0500 E STORAGE  [initandlisten] WiredTiger (-31804) [1454119565:725088][1745:0x7f2ac9534bc0], file:WiredTiger.wt, cursor.next: the process must exit and restart: WT_PANI
C: WiredTiger library panic
2017-03-28T22:06:05.725-0500 I -        [initandlisten] Fatal Assertion 28558

MongoDB 3.2及以后的版本已经很少会出现这样的问题,至少从我接触 MongoDB 到现在还没实际遇到过这个问题,不过既然问题已经发生,我们来看看遇到这种情况应该怎么恢复数据?

如何恢复 MongoDB 数据?

第一招: 从复制集其他节点同步数据

MongoDB 通过复制集能保证高可靠的数据存储,通常生产环境建议使用「3节点复制集」,这样即使其中一个节点崩溃了无法启动,我们可以直接将其数据清掉,重新启动后,以全新的 Secondary 节点加入复制集,它会自动的同步数据,这样也就达到了恢复数据的目的。

然而不幸的是,该用户的 MongoDB 实例 只部署了一个节点 ... 我只能呵呵了 ...

第二招:从最近的一个备份集恢复数据

有的时候可能出现一些极端的case,比如遇到自然灾害,复制集所有节点都挂了(或者像上面的用户这样,你的复制集只部署一个节点...),这时第一招就没法用了。

此时,如果靠谱的你刚好对数据做了备份,此时就排上用场了,比如你每天对 MongoDB 做一次全量备份,那么你就可以把数据恢复到最近一天的数据了;如果你更靠谱的还对数据做了增量本分,能恢复的数据就更多了。

但是可想而知,这个用户既然能部署一个「只有单个节点的复制集」,肯定也不会想到去对数据库进行备份了 ...

第三招: repair 模式启动 MongoDB

当 MongoDB 无法启动时,通常是因为数据文件出现了不一致,mongod 支持以 repair 的模式启动,mongod 会尽可能的尝试自己去修复数据的不一致状态,修复过程中尽可能多的保留有效的数据。

但 repair 也不是对所有的场景都有效,repair 会先加载 MongoDB 所有的集合信息,然后针对每个集合来 repair,如果存储元数据的数据文件损坏,repair 也是没法工作的。

 mongod --repair // 用户尝试按这种方式启动,仍然报相同的错误

第四招:使用 wireditger 工具恢复

以上3招都不行,我的第一想法就是通过 wiredtiger 的 salvage 功能去尽可能的恢复数据(salvage 可翻译为数据打捞,即针对一个wt的数据文件,尽可能多的从中提取有效的数据),本来是想写个工具来做这个事情。不过调研了一下发现

 1. repair 模式启动,实现时也是调用的 wiredtiger 的 salvage 接口实现。
 2. wireditger 自带的一个命令行工具 wt,包含了 salvage 的功能。
 3. 找到一篇使用 wt 工具恢复 MongoDB 数据的文章,写的非常赞。

网友总结的使用 wiredtiger 工具 wt 恢复数据的方法原理很简单,就是通过恢复 wiredtiger 数据文件来恢复MongoDB数据,我实验了一下,的确可行,而且原文的步骤介绍已经非常详细,这里就不再赘述。需要注意的是

  1. MongoDB 3.2 最新版本已经是了 wiredtiger 2.8,所以编译 wt 工具时,可以下载 2.8 版本的 wiredtiger 源代码。
  2. MongoDB 默认会对集合数据进行 snappy 压缩,所以一定要确保 snappy 正确安装,在执行 wt 工具时,通过扩展的形式加载 snappy lib,否则运行时会报错。
  3. 如果需要恢复的集合很多,本文的方法效率是很低的。

第五招:从文件里提取bson文档来恢复

MongoDB json格式的文档,最终是以 BSON (Binary json) 格式持久化存储。

假设我们有个工具叫 bsonextract(有兴趣的同学可以尝试实现下贡献到社区里,直接调 BSON 的接口,实现起来不难),它能从一个数据文件里分析并提取出所有 BSON 格式的内容,那么我们也就达到了恢复数据的目的。

分析时,一段数据满足2个条件,我们即可认为是一个合法的 MongoDB 文档

  • 这段数据是一个合法的 BSON 文档
  • 包含一个 id 字段 (oplog 集合不包含 id 字段,但通常也没有去恢复 oplog 的必要)

上面这个方法不仅只能恢复 wiredtiger 的数据,对 MongoDB 所有存储引擎都有效。

总结

最后,issue SERVER-19815 里介绍了 MongoDB 一直在优化 MongoDB ,让它能在 repair 模式里自动处理各种数据文件损坏(或部分丢失)的场景,目标就是万一遇到数据集损坏的场景,repair都能自动修复掉。

下面是 repair 以后能自动处理的一些场景及处理方法

  • Database files missing

    • An entry for a file will exist in the catalogue, but on disk file is gone
    • Will be impossible to recover from, remove the entry from the catalogue
    • Warn the user strongly about this (Error message)
  • Database files corrupted

    • An entry for a file will exist in the catalogue, but on disk file is unable to be opened
    • Attempt to rename the collection with WiredTiger to a new table that has some mention of it being corrupted in the name
    • Re-create the same collection with the same name (in order to continue repair)
    • Warn the user strongly about this problem, the creation of the new collection
  • Index files missing

    • An entry will exist in the catalogue, but on disk file is gone
    • Build the index as part of repair
  • Index files corrupted

    • An entry will exist in the catalogue, but on disk file is unable to be opened
    • Drop, then rebuild the index as part of repair
  • MongoDB catalogue metadata may be out of alignment with the WT files on disk

    • When something is missing on disk, then this should be resolved by the changes above
    • When something is missing from the catalogue metadata but exists as a wt table on disk we have no recourse. We would need a user accessible function to import
    • If the WiredTiger metadata is corrupt, then the database is corrupt
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
NoSQL MongoDB
MongoDB因服务器异常断电,无法启动异常的修复
本文是博主遇到MongoDB启动异常的解决方法记录,希望对大家有所帮助。
1230 0
|
NoSQL MongoDB
MongoDB服务无法启动,发生服务特定错误:100
问题:MongoDB服务无法启动,发生服务特定错误:100 原因:没有正常关闭mongod服务,导致mongod被锁 解决方案:进入db文件夹,删除mongod.
2245 0
|
NoSQL Shell 数据库
mongoDB因root启动关闭数据库导致mongo普通用户无法启动
  最近,使用mongoDB数据库时,偶然使用了root启停数据库,导致后来mongo用户无法启动数据库,报权限拒绝,但是root可以正常启停mongoDB数据库。
1671 0
|
9天前
|
存储 NoSQL MongoDB
MongoDB如何创建数据库
MongoDB如何创建数据库
|
7天前
|
存储 SQL NoSQL
什么是 MongoDB,为什么它是当今最受欢迎的数据库之一?
什么是 MongoDB,为什么它是当今最受欢迎的数据库之一?
|
9天前
|
JSON NoSQL MongoDB
理解Nosql数据库的mongodb
【5月更文挑战第5天】MongoDB是2009年发布的一款通用型NoSQL数据库,结合了关系模型和NoSQL的优点,适用于各种现代应用。其特点包括图形界面、数据服务、云基础设施集成(AWS, Azure, Google Cloud)。它具备全面的查询能力、ACID事务、可调整的一致性保证,并有多语言驱动及工具,可在任何地方运行。
73 4
|
9天前
|
存储 NoSQL MongoDB
MongoDB数据库转换为表格文件的Python实现
MongoDB数据库转换为表格文件的Python实现
46 0
|
9天前
|
存储 NoSQL 关系型数据库
Percona XtraBackup是否支持MongoDB数据库备份?
【5月更文挑战第13天】Percona XtraBackup是否支持MongoDB数据库备份?
37 1

相关产品

  • 云数据库 MongoDB 版