我有一个曾经很大的MongoDB数据库(> 3GB)。从那时起,文档已被删除,我希望数据库文件的大小相应减少。
但是由于MongoDB保留了分配的空间,因此文件仍然很大。
我在这里和那里读到,admin命令mongod --repair
用于释放未使用的空间,但我没有足够的空间来运行此命令。
你知道我可以释放闲置空间吗?
答案 0 :(得分:144)
compact
命令和 WiredTiger 更新:,它看起来像extra disk space will actually be released to the OS。
UPDATE:从v1.9开始+有一个compact
命令。
此命令将执行“内联”压缩。它仍然需要一些额外的空间,但不是那么多。
MongoDB通过以下方式压缩文件:
您可以通过运行mongod --repair
或直接连接并运行db.repairDatabase()
来执行此“压缩”。
在任何一种情况下,您都需要在某处复制文件的空间。现在我不知道为什么你没有足够的空间来执行压缩,但是,如果你有另一台有更多空间的计算机,你确实有一些选择。
mongoexport
),然后您可以导入同一个数据库(使用mongoimport
)。这将导致更加压缩的新数据库。现在,您可以使用新的数据库文件停止原始mongod
替换,并且您可以继续使用。目前还没有一种使用Mongo“紧凑到位”的好方法。 Mongo绝对可以占用很多空间。
现在压缩的最佳策略是运行主从设置。然后你可以压缩奴隶,让它赶上并切换它们。我知道还有点毛茸茸的。也许Mongo团队会提出更好的压实,但我不认为它在他们的名单上很高。目前假设驱动器空间很便宜(通常是这样)。
答案 1 :(得分:37)
我遇到了同样的问题,只需在命令行执行此操作即可解决:
mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename
答案 2 :(得分:31)
看起来Mongo v1.9 +已经支持紧凑型了!
> db.runCommand( { compact : 'mycollectionname' } )
请参阅此处的文档:http://docs.mongodb.org/manual/reference/command/compact/
“与repairDatabase不同,compact命令不需要双磁盘空间来完成它的工作。它在工作时需要少量的额外空间。另外,compact更快。”
答案 3 :(得分:14)
压缩当前数据库中的所有集合
db.getCollectionNames().forEach(function (collectionName) {
print('Compacting: ' + collectionName);
db.runCommand({ compact: collectionName });
});
答案 4 :(得分:13)
如果您需要进行完整修复,请使用repairpath
选项。将其指向具有更多可用空间的磁盘。
例如,在我的Mac上我使用过:
mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair
更新:根据MongoDB Core Server Ticket 4266,您可能需要添加--nojournal
以避免错误:
mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal
答案 5 :(得分:11)
从2.8 version of Mongo, you can use compression开始。你将使用WiredTiger引擎进行3级压缩,mmap(默认情况下2.6不提供压缩):
以下是您可以为16 GB数据保存多少空间的示例:
数据来自this文章。
答案 6 :(得分:7)
我们需要基于StorageEngine解决2种方法。
<强> 1。 MMAP()引擎:
命令: db.repairDatabase()
注意: repairDatabase需要的可用磁盘空间等于当前数据集的大小加上2千兆字节。如果保存dbpath的卷缺少足够的空间,则可以装入单独的卷并将其用于修复。为repairDatabase安装单独的卷时,必须从命令行运行repairDatabase,并使用--repairpath开关指定用于存储临时修复文件的文件夹。 例如:想象数据库大小为120 GB意味着,(120 * 2)+2 = 242 GB所需的硬盘空间。
另一种收集方式, 命令: db.runCommand({compact:&#39; collectionName&#39;})
<强> 2。 WiredTiger:强> 它自动解决了它自己。
答案 7 :(得分:4)
如果从集合中删除了大量数据,并且集合从不将删除的空间用于新文档,则需要将此空间返回到操作系统,以便其他数据库或集合可以使用它。您需要运行压缩或修复操作,以便对磁盘空间进行碎片整理并重新获得可用空间。
压缩过程的行为取决于MongoDB引擎,如下所示
db.runCommand({compact: collection-name })
<强> MMAPv1 强>
压缩操作对数据文件进行碎片整理&amp;索引。但是,它不会释放操作系统的空间。该操作对于碎片整理和创建更多连续空间以供MongoDB重用仍然有用。但是,当可用磁盘空间非常低时,它没有用。
在压缩操作期间,需要额外的磁盘空间,最多2GB。
在压缩操作期间保持数据库级锁定。
<强> WiredTiger 强>
WiredTiger引擎默认提供压缩,比MMAPv1消耗更少的磁盘空间。
紧凑型进程释放了操作系统的可用空间。 运行压缩操作需要最小的磁盘空间。 WiredTiger还会阻止数据库上的所有操作,因为它需要数据库级锁定。
对于 MMAPv1 引擎,compact doest不会将空间返回给操作系统。您需要运行修复操作以释放未使用的空间。
db.runCommand({repairDatabase: 1})
答案 8 :(得分:4)
MongoDB中的空间回收存在一些相当大的混淆,一些推荐的做法在某些部署类型中是非常危险的。更多详情如下:
TL; DR repairDatabase
尝试从试图从磁盘损坏中恢复的独立MongoDB部署中抢救数据。如果它恢复空间,则纯粹是副作用。恢复空间永远不应该是运行repairDatabase
的主要考虑因素。
WiredTiger:对于具有WiredTiger的独立节点,运行compact
将释放操作系统空间,但需要注意一点:MongoDB 3.0.x上WiredTiger上的compact
命令受此错误的影响:SERVER-21833已在MongoDB 3.2.3中修复。在此版本之前,WiredTiger上的compact
可能会无声地失败。
MMAPv1:由于MMAPv1的工作方式,使用MMAPv1存储引擎没有安全且受支持的方法来恢复空间。 MMAPv1中的compact
将对数据文件进行碎片整理,可能为新文档提供更多可用空间,但不会将空间释放回操作系统。
如果您完全了解此潜在危险命令(见下文)的后果,可能能够运行repairDatabase
,因为repairDatabase
基本上通过丢弃损坏的文档来重写整个数据库。作为副作用,这将创建新的MMAPv1数据文件,而不会产生任何碎片,并将空间释放回操作系统。
对于不太冒险的方法,在MMAPv1部署中也可以运行mongodump
和mongorestore
,具体取决于部署的大小。
对于副本集配置,恢复空间的最佳和最安全的方法是为WiredTiger和MMAPv1执行initial sync。
如果需要从集合中的所有节点恢复空间,则可以执行滚动初始同步。也就是说,在最后逐步降低主要并在其上执行初始同步之前,在每个辅助节点上执行初始同步。滚动初始同步方法是执行副本集维护的最安全方法,它也不会将停机时间作为奖励。
请注意,执行滚动初始同步的可行性还取决于部署的大小。对于非常大的部署,执行初始同步可能不太可行,因此您的选项稍微有限。如果使用了WiredTiger,则可能能够从该集合中取出一个辅助节点,以独立方式启动它,在其上运行compact
,然后将其重新加入该集合。
repairDatabase
请不要在副本集节点上运行repairDatabase
。这非常危险,如repairDatabase page中所述,并在下面详细介绍。
名称repairDatabase
有点误导,因为命令不会尝试修复任何内容。该命令旨在在独立节点上出现磁盘损坏时使用,这可能导致文档损坏。
repairDatabase
命令可以更准确地描述为&#34;打捞数据库&#34;。也就是说,它通过丢弃损坏的文档来重新创建数据库,以试图让数据库进入一个可以启动它并从中挽救完整文档的状态。
在MMAPv1部署中,重建数据库文件会将操作系统的空间释放为副作用。释放操作系统的空间绝不是目的。
repairDatabase
对副本集在副本集中,MongoDB期望集合中的所有节点都包含相同的数据。如果在副本集节点上运行repairDatabase
,则该节点可能包含未检测到的损坏,repairDatabase
将尽职地删除损坏的文档。
可以预见,这使得该节点包含与集合其余部分不同的数据集。如果更新恰好击中该单个文档,整个集合可能会崩溃。
更糟糕的是,这种情况完全有可能长时间处于休眠状态,只是在没有明显原因的情况下突然发作。
答案 9 :(得分:3)
Mongodb 3.0及更高版本有一个新的存储引擎--WiredTiger。 在我的情况下,交换引擎将磁盘使用量从100 Gb减少到25 Gb。
答案 10 :(得分:1)
数据库文件的大小不能减小。在“修复”数据库时,mongo服务器只能删除其中的一些文件。如果删除了大量数据,mongo服务器将在修复期间“释放”(删除)一些现有文件。
答案 11 :(得分:1)
一般来说,compact比repairDatabase更可取。但是,修复compact的一个优点是可以对整个集群进行修复。紧凑,你必须登录每个碎片,这有点烦人。
答案 12 :(得分:0)
在分片群集的情况下,不建议使用mongoDB -repair。
如果使用副本集分片群集,请使用紧凑命令,它将重写和整理所有集合的所有数据和索引文件。 语法:
db.runCommand( { compact : "collection_name" } )
当与force:true一起使用时,compact在副本集的主副本上运行。
例如 db.runCommand ( { command : "collection_name", force : true } )
要考虑的其他要点: -它阻止了操作。因此建议在维护窗口中执行。 -如果副本集在不同的服务器上运行,则需要分别在每个成员上执行 -对于分片群集,压缩需要分别在每个分片成员上执行。无法针对mongos实例执行。
答案 13 :(得分:0)
对于独立模式,您可以使用压缩或修复,
对于分片群集或副本集,以我的经验,在主数据库上运行压缩,然后在辅助数据库上压缩之后,主数据库的大小减小了,但没有减小。 您可能需要执行resync member来减少辅助数据库的大小。通过这样做,您可能会发现辅助数据库的大小甚至比主数据库减小了很多,我猜这个compact命令并没有真正压缩集合。 因此,我结束了switching the primary and secondary of the replica set,然后再次做resync member。
我的结论是,减小分片/副本集大小的最佳方法是执行重新同步成员,切换主从节点并再次重新同步。
答案 14 :(得分:-5)
只有一种方式,我能够做到这一点。不保证现有数据的安全性。尝试自己承担风险。
直接删除数据文件并重启mongod。
例如,使用ubuntu(数据的默认路径:/ var / lib / mongodb),我有几个文件的名称如:collection。#。我保留了collection.0并删除了所有其他内容。
如果您在数据库中没有严重的数据,似乎更容易。