MongoDB 数据库集合损坏?

4

我有一个分片的Mongo 2.4.3设置。

当我尝试在我的某个集合上运行查询时,会收到错误消息exception: BSONObj size: 0 (0x00000000) is invalid. Size must be between 0 and 16793600(16MB) First element: EOO

我已经运行了db.repairDatabase,但似乎没有什么帮助。

当我只做 db.collection.findOne() 时,运行正常,但是当我例如进行 db.collection.find({'_id': {'$gte': ObjectId("52631d000000000000000000")}} 这样的操作时,就会出现上述错误。

我已经读到这可能是由于损坏的索引导致的,所以我尝试过:

db.collection.reIndex();
{
    "raw" : {
        "rs0/ec2-xx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com:27017,ec2-xx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com:27017,ec2-xx-xx-xxx-xx.us-west-2.compute.amazonaws.com:27017" : {
            "nIndexesWas" : 2,
            "errmsg" : "exception: BSONObj size: 0 (0x00000000) is invalid. Size must be between 0 and 16793600(16MB) First element: EOO",
            "code" : 10334,
            "ok" : 0
        }
    },
    "ok" : 0,
    "errmsg" : "{ rs0/ec2-xx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com:27017,ec2-xx-xxx-xxx-xxx.us-west-2.compute.amazonaws.com:27017,ec2-xx-xxx-xxx-xx.us-west-2.compute.amazonaws.com:27017: \"exception: BSONObj size: 0 (0x00000000) is invalid. Size must be between 0 and 16793600(16MB) First element: EOO\" }"
}

在执行此操作之前,我已删除了所有索引,仅保留了 _id 上的索引。

db.collection.getIndexes();
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "db.collection",
        "name" : "_id_"
    }
]

我还没有运气,而且我已经没有更多的想法了。有人有其他的建议吗?这个集合大约有9亿个文档,所以我真的需要恢复它。


你试过先删除索引,而不是直接重新建立索引吗? - Sammaye
唯一剩下的索引是在_id上的,它不能被删除,所有其他索引都已经被删除。 - Pieter De Schepper
我认为索引修复永远不会起作用。BSON 对象已经损坏,这是您的主要集合。我曾经遇到过同样的问题,但它可以正常工作。让我查看内部文档信息,看看我能否提供帮助。 - Maximiliano Rios
1个回答

6
如果您已经成功运行了修复操作,那么您已经彻底重写了所有数据并重新构建了索引,因此您已经拥有一个全新的_id索引-实际上,您已经删除并重建了该索引。
您拥有一个副本集(rs0),那么如果您撤销当前的主节点会发生什么?-其他节点上的损坏是否也存在,还是只有一个?
如果只有一个(或至少有一个没有问题的节点),则清除带有损坏的实例并使它们重新同步,它将从其余“良好”节点中提取数据并消除损坏。这将是摆脱此类损坏的首选方法(远远超过其他方法),这是副本集的首要用途之一。
如果这不是一个选择,并且所有节点都显示相同的问题(这将很奇怪),那么您应该尝试执行以下操作:
  1. 使用--repair运行整个实例(即关闭mongod进程,然后重新启动),并让它从头开始重建所有数据(本地、所有数据库、所有索引)。
  2. 仅当且仅当这样做无法消除损坏时,最后的尝试方法是尝试mongodump --repair - 这种方法将尝试所有合理的方法来解决问题,并可能产生重复文档(取决于损坏的程度)。因此,您可能需要比mongod最初用于存储所使用的更多磁盘空间才能完成此操作。

最后,您应该升级到较新的MongoDB版本,特别是在分片环境中。截至撰写本答案时,当前版本为2.4.9,其中包含几个重要的错误修复 - 完整信息可以在mongodb-announce的发布公告中找到。


当我在PRIMARY上运行时,我得到:rs0:PRIMARY> db.collection.find({'_id':{'$gte':ObjectId('52631d000000000000000000')}}).limit(1); 错误: { "$err" : "getFile(): bad file number value (corrupt db?): run repair", "code" : 10295 } - Pieter De Schepper
1
这意味着你有一个备用的主机?为什么不直接使用备用主机的数据呢?将主机降级,让备用主机成为主机,然后重新同步旧的主机。 - Asya Kamsky
重要事实:mongodump --repair 仅适用于使用 mmapv1 存储引擎的 mongod 实例。您不能在 mongos 或使用 wiredTiger 存储引擎的 mongod 实例上运行 --repair。要修复使用 wiredTiger 的 mongod 实例中的数据,请使用 mongod --repair - Stefan Rogin
这是一个值得注意的事情,但忽略这些信息的原因是在编写时WT并不存在作为一个选项,并且问题明确指定与版本2.4.3相关。 - Adam Comerford

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接