【问题标题】:Mongo database taking much more disk space than it shouldMongo 数据库占用的磁盘空间比应有的多得多
【发布时间】:2013-04-25 07:23:17
【问题描述】:

在我的 mongo 数据库中,我有一个 5GB 的集合,一个 10MB 的集合,还有几个没有上限的集合。没有封顶的文件包含超过 20 个小文档。

经过长时间 (4h) 压力测试(仅写入 5GB 上限集合),我的数据库使用 18GB。

这就是我的 db.stats 所说的(以 MB 为单位的值):

data-db:PRIMARY> db.stats(1024*1024)
{
    "db" : "data",
    "collections" : 9,
    "objects" : 8723395,
    "avgObjSize" : 208.8405255064112,
    "dataSize" : 1737,
    "storageSize" : 5130,
    "numExtents" : 12,
    "indexes" : 19,
    "indexSize" : 2534,
    "fileSize" : 18423,
    "nsSizeMB" : 16,
    "ok" : 1
}

这是 5GB 的收集统计信息(值以 MB 为单位):

data-db:PRIMARY> db.sms_message_event.stats(1024*1024)
{
    "ns" : "data.sms_message_event",
    "count" : 8723300,
    "size" : 1737,
    "avgObjSize" : 0.00019912189194456226,
    "storageSize" : 5120,
    "numExtents" : 3,
    "nindexes" : 6,
    "lastExtentSize" : 1026,
    "paddingFactor" : 1,
    "systemFlags" : 1,
    "userFlags" : 0,
    "totalIndexSize" : 2534,
    "indexSizes" : {
        "_id_" : 395,
        "t_1_when_-1" : 475,
        "smsc_message_id_1" : 185,
        "user_id_1_t_1_when_1" : 481,
        "message_id_1" : 318,
        "virtual_number_recipient_when_index" : 678
    },
    "capped" : true,
    "max" : 2147483647,
    "ok" : 1
}

那么为什么 fileSize 比 storageSize 大这么多呢?我现在什至无法运行 repairDatabase() ,但我在每个非上限集合上尝试了 compact() ,但没有结果。实际上,这是预料之中的,因为 db 在压力测试之前是干净的。我的意思是文件被删除了,不仅仅是收藏被删除了。

从日志中,我可以看到在压力测试期间以大约 1 小时的间隔创建了额外的数据文件。

部分日志:http://pastie.org/private/t8u9caxstafbjdybgwtsfw

更新:又过了一个晚上,又通过了 4 小时压力测试,它是 28GB :(

data-db:PRIMARY> db.stats(1024*1024)
{
    "db" : "data",
    "collections" : 9,
    "objects" : 8724995,
    "avgObjSize" : 208.840894006243,
    "dataSize" : 1737,
    "storageSize" : 5130,
    "numExtents" : 12,
    "indexes" : 19,
    "indexSize" : 2590,
    "fileSize" : 28658,
    "nsSizeMB" : 16,
    "ok" : 1
}

【问题讨论】:

  • 这就是 mongoDB 的工作方式……它将数据文件预分配到特定大小。你可以在这里阅读更多信息:docs.mongodb.org/manual/faq/storage
  • 如果这是一个小型数据库,您可能希望使用smallfiles,它使用的默认数据文件大小要小得多......docs.mongodb.org/manual/reference/configuration-options/…
  • 好吧,但我知道它会提前预分配一个文件。分配的最大文件大小为 2GB。我们的数据有 5GB - 请参阅 storageSize(仅插入,不删除,因为这是一个上限集合)。怎么总变成了 18GB?
  • 您也可以将 --noprealloc 与 --smallfiles 或不一起使用。这些都有很好的记录,并且经常被问到这里。
  • CompactRepair 本质上是相同的。修复数据库会重新创建数据文件和索引,并会减少实际磁盘空间的使用。 compact 命令将重写单个集合并对其进行碎片整理,但不会释放任何物理磁盘空间。修复将从头开始重写文件(类似于完全重新同步辅助节点)并将回收磁盘空间,但最多需要 2* 磁盘空间才能完成。 db.stats()在压力测试前报告了什么?您在使用彩信吗?

标签: mongodb


【解决方案1】:

发生这种情况是因为 MongoDB 在重新使用为上限集合分配的空间时出现错误。它已被归档为SERVER-9489,将被分类并希望尽快修复。

在不耗尽磁盘空间的情况下继续运行压力测试的方法是在测试完成后删除测试数据库目录,然后在运行新测试时创建一个新目录(假设您不需要重复使用相同的数据)。如果您确实需要相同的数据,您可以使用 mongodump 将其保存在每次运行中,但可能还有其他更简单的选项,具体取决于您的具体使用情况。

【讨论】:

  • 或者,您可以将上限集合放在单独的数据库和 dropDatabase 中,并在运行之间重新创建它 - 这将释放所有空间。
  • 谢谢。另一种选择是在辅助节点上停止 mongod,删除文件,然后重新启动它。它在 replSet 中,所以当它在生产环境中出现时,这是一种可行的方法。不过,我希望它会更早修复。
猜你喜欢
  • 2011-02-10
  • 2014-10-06
  • 2018-07-22
  • 1970-01-01
  • 2015-10-07
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多