无法弄清楚为什么 mongo 数据库在迁移后变大了?

Can't figure out why mongo database becomes bigger after migration?

我是 mongodb 的新手。我有一个本地服务器和一个远程服务器。使用mongodump/mongorestore工具将mongo数据库从本地服务器迁移到远程服务器后,我发现远程服务器上的数据库变大了。

这是我的示例:

在本地服务器上(Ubuntu 14.04.2 LTS,mongo 3.0.5):

> show dbs
Daily_data      7.9501953125GB
Monthly_data    0.453125GB
Weekly_data     1.953125GB

在远程服务器上(CentOS 6.7,mongo 2.4.3):

> show dbs
Daily_data      9.94921875GB
Monthly_data    0.953125GB
Weekly_data     3.9521484375GB

我还检查了一个集合的状态进行比较,计数相同但大小(如 indexSizetotalIndexSize 等)发生了变化:

这是本地服务器上的收集状态:

> db.original_prices.stats()
{
    "ns" : "Daily_data.original_prices",
    "count" : 9430984,
    "size" : 2263436160,
    "avgObjSize" : 240,
    "numExtents" : 21,
    "storageSize" : 2897301504,
    "lastExtentSize" : 756662272,
    "paddingFactor" : 1,
    "paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.",
    "userFlags" : 1,
    "capped" : false,
    "nindexes" : 2,
    "indexDetails" : {

    },
    "totalIndexSize" : 627777808,
    "indexSizes" : {
        "_id_" : 275498496,
        "symbol_1_dateTime_1" : 352279312
    },
    "ok" : 1
}

这是远程服务器上的收集状态:

> db.original_prices.stats()
{
    "ns" : "Daily_data.original_prices",
    "count" : 9430984,
    "size" : 1810748976,
    "avgObjSize" : 192.00000508960676,
    "storageSize" : 2370023424,
    "numExtents" : 19,
    "nindexes" : 2,
    "lastExtentSize" : 622702592,
    "paddingFactor" : 1,
    "systemFlags" : 1,
    "userFlags" : 0,
    "totalIndexSize" : 639804704,
    "indexSizes" : {
        "_id_" : 305994976,
        "symbol_1_dateTime_1" : 333809728
    },
    "ok" : 1
}

如果mongodump/mongorestore迁移mongo数据库是一个好的保存方式?

可能影响 collection 磁盘大小的因素包括底层硬件、文件系统和配置。在您的情况下,主要因素似乎是本地和远程服务器上使用的存储引擎不同:您的本地服务器是 运行 Mongo 3.0,而远程服务器是 运行 较旧的版本。基于 paddingFactorNote 属性 的存在,这是显而易见的,但是您可以在两种环境中通过 运行 db.version() 确认。

在 Mongo 2.4/2.6 和 Mongo 3.0 之间,collection 的存储方式发生了一些重要变化,尤其是添加了 WiredTiger 存储引擎作为默认的 mmapv1 存储引擎。在分配期间,mmapv1 引擎(您正在使用的引擎)填充文档的方式也发生了变化,以适应文档大小的增长。

造成大小差异的另一个主要原因是您对 mongorestore 的使用。在正常使用期间,mongo 数据库不会以最小化磁盘使用的方式存储。但是,mongorestore 以紧凑的方式重建 database/collection,这就是为什么对于您发布的 collection,远程 storageSize 较小。

您似乎已经注意到这里的问题是索引,因为清楚地表明它是这里增长的 indexSize,并且有一个完全合乎逻辑的解释。

当运行恢复时,索引被重建,但在某种程度上避免阻塞恢复操作中发生的其他写入操作。这与文档中描述的 Build Indexes in the Background 中使用的过程相似,不完全相同但接近。

为了获得最佳索引大小,最好先从目标数据库中删除索引,然后将 --noIndexRestore 选项与 mongorestore 命令一起使用,因为这会阻止在数据加载。

然后完成后,您可以 运行 常规 createIndex 排除 "background" 选项的任何使用,以便在前台创建索引。结果将是在创建索引期间数据库将被阻止读取和写入,但生成的索引的大小将更小。

至于一般做法,您会注意到其他数据大小实际上会出现 "smaller",就像在 "rebuilding" 的过程中一样,然后源中存在任何松弛 space恢复数据时不会创建。

来自 mongodump 的数据采用二进制格式,应始终优先使用 mongoexport 和相关 mongoimport 的文本格式,当然当从一个MongoDB 实例并在另一个实例上使用,因为这不是这些工具的目的。

其他备用 ae 文件系统副本,例如 LVM 快照,当然会恢复到与创建备份副本完全相同的状态。