我有一个 MongoDB 数据库,它曾经很大(> 3 GB)。从那时起,文档已经被删除,我预计数据库文件的大小将相应减少。
但是因为 MongoDB 保持分配的空间,所以文件仍然很大。
我到处读到管理命令 mongod --repair用于释放未使用的空间,但是磁盘上没有足够的空间来运行这个命令。
mongod --repair
你知道有什么办法可以腾出闲置的空间吗?
更新: 使用 compact命令 还有 WiredTiger,它看起来像 额外的磁盘空间实际上将被释放给操作系统。
compact
更新: 在 v1.9 + 中有一个 compact命令。
这个命令将执行一个“嵌入式”压缩。它仍然需要一些额外的空间,但不会太多。
MongoDB 通过以下方式压缩文件:
您可以通过运行 mongod --repair或直接连接并运行 db.repairDatabase()来进行这种“压缩”。
db.repairDatabase()
无论哪种情况,您都需要在某个地方留出空间来复制文件。现在我不知道为什么你没有足够的空间来进行压缩,但是,你有一些选择,如果你有另一台电脑更大的空间。
mongoexport
mongoimport
mongod
目前还没有一个好的方法来使用 Mongo“就地压缩”。而且 Mongo 肯定会占用很多空间。
目前压缩的最佳策略是运行主从设置。然后你可以压缩奴隶,让它赶上并切换它们。我知道还是有点毛茸茸的。也许 Mongo 团队会提出更好的地方压实,但我不认为这是他们的高清单。驱动器空间目前被认为是便宜的(而且通常是便宜的)。
看起来 Mongo v1.9 + 已经支持了紧凑版本!
> db.runCommand( { compact : 'mycollectionname' } )
看看这里的文件: http://docs.mongodb.org/manual/reference/command/compact/
”与 repirDatabase 不同,紧凑命令不需要两个磁盘空间来完成其工作。它确实需要少量的额外空间,而工作。此外,紧凑型车更快。”
不能减小数据库文件的大小。在“修复”数据库时,mongo 服务器只能删除其中的一些文件。如果大量数据已被删除,mongo 服务器将“释放”(删除) ,在修复期间,其现有的一些文件。
如果需要运行完全修复,请使用 repairpath选项。将其指向具有更多可用空间的磁盘。
repairpath
例如,在我的 Mac 上,我使用了:
mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair
更新: 根据 MongoDB 核心服务器票4266,您可能需要添加 --nojournal以避免错误:
--nojournal
mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal
我也遇到了同样的问题,只需在命令行中执行此操作即可解决:
mongodump -d databasename echo 'db.dropDatabase()' | mongo databasename mongorestore dump/databasename
一般来说,压缩优于修复数据库。但是与紧凑型相比,修复的一个优势是您可以对整个集群进行修复。你必须登录每个碎片,这有点烦人。
压缩当前数据库中的所有集合
db.getCollectionNames().forEach(function (collectionName) { print('Compacting: ' + collectionName); db.runCommand({ compact: collectionName }); });
只是我能做到的一种方式。不能保证您现有数据的安全。你自己去冒险吧。
直接删除数据文件,重新启动蒙神。
例如,对于 ubuntu (默认的数据路径:/var/lib/mongodb) ,我有两个名为: Collection 的文件。#.我保持收集。0和删除所有其他。
如果数据库中没有严肃的数据,这似乎是一种更简单的方法。
当我遇到同样的问题时,我停止了 mongo 服务器,用 command 重新启动它
在运行修复操作之前,您应该检查您的硬盘上是否有足够的空闲空间(最小值是您的数据库的大小)
从 Mongo 的2.8版本,可以使用压缩开始。使用 WiredTiger 引擎 mmap (2.6中默认不提供压缩) ,您将有3个压缩级别:
这里有一个例子,可以说明为16GB 的数据节省多少空间:
数据取自 这个文章。
我们需要解决两种方法,基于存储引擎。
1. MMAP ()引擎:
命令: 数据库()
注意: 修复数据库需要的空闲磁盘空间等于当前数据集的大小加上2GB。如果保存 dbpath 的卷缺乏足够的空间,可以挂载一个单独的卷并使用它进行修复。在安装一个单独的恢复数据库卷时,您必须从命令行运行 repirDatabase,并使用—— repirpath 开关指定用于存储临时修复文件的文件夹。 假设数据库大小是120GB 的意思,(120 * 2) + 2 = 所需的 242GB 硬盘空间。
另一种收藏方式, 命令: < strong > db.runCommand ({ compact: ‘ CollectionName’})
2. 《连线虎》 : 它自动解决它-自己。
Mongodb 3.0及更高版本有一个新的存储引擎—— WiredTiger。 在我的案例中,切换引擎将磁盘使用量从100Gb 减少到25Gb。
如果从集合中删除了大量数据,而且集合从未为新文档使用已删除的空间,则需要将该空间返回给操作系统,以便其他数据库或集合可以使用该空间。您将需要运行一个压缩或修复操作,以便对磁盘空间进行碎片整理并重新获得可用的可用空间。
压缩过程的行为依赖于 MongoDB 引擎,如下所示
db.runCommand({compact: collection-name })
MMAPv1
压缩操作对数据文件和索引进行碎片整理。但是,它不向操作系统释放空间。该操作对于整理碎片并创建更多连续空间以供 MongoDB 重用仍然很有用。但是,当可用磁盘空间非常小时,这是没有用的。
在压缩操作期间,需要额外的最多2GB 的磁盘空间。
在压缩操作期间持有数据库级锁。
连线虎
WiredTiger 引擎默认提供了比 MMAPv1消耗更少的磁盘空间的压缩。
紧凑进程向操作系统释放可用空间。 运行紧凑操作需要最小的磁盘空间。 WiredTiger 还阻止数据库上的所有操作,因为它需要数据库级别的锁。
对于 MMAPv1发动机,紧凑型不返回操作系统的空间。您需要运行修复操作来释放未使用的空间。
db.runCommand({repairDatabase: 1})
MongoDB 中的空间回收存在一些相当大的混淆,一些推荐的实践在某些部署类型中完全是危险的。更多详情如下:
repairDatabase尝试从试图从磁盘损坏恢复的独立 MongoDB 部署中抢救数据。如果它恢复空间,它是 纯粹是副作用。恢复空间永远不应该成为运行 repairDatabase的主要考虑因素。
repairDatabase
WiredTiger: 对于使用 WiredTiger 的独立节点,运行 compact将向操作系统释放空间,但需要注意的是: MongoDB 3.0.x 上的 WiredTiger 上的 compact命令受到了这个 bug 的影响: 服务器编号21833在 MongoDB 3.2.3中修复了。在此版本之前,WiredTiger 上的 compact可能无声无息地失败。
MMAPv1: 由于 MMAPv1的工作方式,使用 MMAPv1存储引擎恢复空间没有安全且受支持的方法。MMAPv1中的 compact将对数据文件进行碎片整理,可能为新文档提供更多的空间,但不会将空间释放回操作系统。
如果您完全理解这个 潜在的危险命令的后果(见下文) ,那么您就能够运行 repairDatabase,因为 repairDatabase实际上是通过丢弃损坏的文档来重写整个数据库的。作为一个副作用,这将创建新的 MMAPv1数据文件没有任何碎片,并释放空间回操作系统。
对于不那么冒险的方法,在 MMAPv1部署中也可以运行 mongodump和 mongorestore,这取决于部署的大小。
mongodump
mongorestore
对于副本集配置,恢复空间的最佳和最安全的方法是对 WiredTiger 和 MMAPv1执行 初始同步。
如果需要从集合中的所有节点恢复空间,可以执行滚动初始同步。也就是说,在最终退出主服务器并对其执行初始同步之前,对每个辅助服务器执行初始同步。滚动初始同步方法是执行副本集维护最安全的方法,而且它不包括停机时间作为奖励。
请注意,执行滚动初始同步的可行性也取决于部署的大小。对于非常大的部署,进行初始同步可能是不可行的,因此您的选项比较有限。如果使用 WiredTiger,则 梅能够从集合中取出一个辅助设备,将其作为独立设备启动,在其上运行 compact,并将其重新加入到集合中。
请不要在复制集节点 上运行 repairDatabase。这是非常危险的,正如在 数据库页中提到的,并在下面详细描述。
repairDatabase这个名称有点误导人,因为该命令不试图修复任何东西。该命令用于当 独立节点独立节点上存在磁盘损坏时,这可能导致损坏文档。
repairDatabase命令可以更准确地描述为“抢救数据库”。也就是说,它通过丢弃损坏的文档来重新创建数据库,从而使数据库进入一种状态,您可以在这种状态下启动数据库并从中挽救完整的文档。
在 MMAPv1部署中,这种数据库文件的重新构建将空间释放到操作系统 作为副作用。向操作系统释放空间从来都不是目的。
在副本集中,MongoDB 期望集中的所有节点都包含相同的数据。如果在复制集节点上运行 repairDatabase,则该节点有可能包含未检测到的损坏,而 repairDatabase将尽职地为您删除损坏的文档。
可以预见的是,这会使该节点包含与集合其余部分不同的数据集。如果一个更新碰巧击中了那个文档,那么整个集合就会崩溃。
更糟糕的是,这种情况完全有可能长时间处于休眠状态,只是突然发生,没有明显的原因。
不建议在分片集群情况下修复 mongoDB。
如果使用复制集分片集群,使用压缩命令,它将重写和碎片化所有集合的所有数据和索引文件。 句法:
db.runCommand( { compact : "collection_name" } )
当使用强制: 真,紧凑运行在主副本集。 例如 db.runCommand ( { command : "collection_name", force : true } )
db.runCommand ( { command : "collection_name", force : true } )
需要考虑的其他问题: - 它会阻止操作。所以建议在维护窗口执行。 - 如果副本集运行在不同的服务器上,则需要分别在每个成员上执行 - 如果是分片集群,则需要分别对每个分片成员执行压缩。不能对 mongo 实例执行压缩。
对于独立模式,你可以使用压缩或修理,
对于分片集群或副本集,根据我的经验,在主数据库上运行压缩之后,接着压缩辅助数据库,主数据库的大小会减小,但辅助数据库的大小不会减小。 您可能希望使用 重新同步成员来减小辅助数据库的大小。通过这样做,您可能会发现辅助数据库的大小甚至比主数据库更小,我猜想压缩命令并没有真正压缩集合。 所以,我选择了 切换副本集的主副本然后又选择了 重新同步成员。
我的结论是,减少分片/副本集大小的最佳方法是通过重新同步成员,切换主辅助,并重新同步。