减lessMongoDB数据库文件大小

我有一个曾经很大(> 3GB)的MongoDB数据库。 从那时起,文件已被删除,我期望数据库文件的大小相应减less。

但是由于MongoDB保持分配的空间,文件仍然很大。

我在这里和那里读到,pipe理命令mongod --repair用于释放未使用的空间,但是我没有足够的空间来运行此命令。

你知道一个方法可以释放未使用的空间吗?

更新:compact命令 WiredTiger它看起来多余的磁盘空间将实际上释放到操作系统 。


更新:从v1.9 +有一个compact命令。

该命令将执行“in-line”压缩。 它仍然需要一些额外的空间,但不是那么多。


MongoDB通过以下方式压缩文件:

  • 将文件复制到新的位置
  • 循环遍历文档并重新sorting/重新解决它们
  • 用新文件replace原始文件

您可以通过运行mongod --repair或直接连接并运行db.repairDatabase()来执行此“压缩”。

无论哪种情况,您都需要在某处复制文件。 现在我不知道为什么你没有足够的空间来执行压缩,但是,如果你有另外一台有更多空间的计算机,你也有一些select。

  1. 将数据库导出到安装了Mongo的另一台计算机(使用mongoexport ),然后导入同一个数据库(使用mongoimport )。 这将导致一个更加压缩的新数据库。 现在你可以停止原来的mongodreplace新的数据库文件,你很好去。
  2. 停止当前的mongod并将数据库文件复制到一台更大的计算机并在该计算机上运行修复。 然后,您可以将新的数据库文件移回原始计算机。

目前还没有一个好的方法来使用Mongo进行“压缩”。 而Mongo绝对可以吸取很多空间。

目前压缩的最佳策略是运行主从设置。 你可以紧凑的奴隶,让它赶上并切换。 我还是有点毛。 也许Mongo团队会提出更好的压缩,但我不认为他们的名单上的高。 驱动器空间目前被认为是便宜的(通常是)。

我有同样的问题,并通过在命令行简单地做到这一点解决:

 mongodump -d databasename echo 'db.dropDatabase()' | mongo databasename mongorestore dump/databasename 

它看起来像Mongo v1.9 +支持紧凑的地方!

 > db.runCommand( { compact : 'mycollectionname' } ) 

请参阅这里的文档: http : //docs.mongodb.org/manual/reference/command/compact/

“与repairDatabase不同的是,compact命令不需要双磁盘空间来完成工作,在工作时需要less量的额外空间,另外,compact更快。

如果需要运行完整修复,请使用修复repairpath选项。 将其指向具有更多可用空间的磁盘。

例如,在我的Mac上,我用过:

 mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair 

更新:每MongoDB核心服务器票务4266 ,您可能需要添加--nojournal以避免错误:

 mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal 

压缩当前数据库中的所有集合

 db.getCollectionNames().forEach(function (collectionName) { print('Compacting: ' + collectionName); db.runCommand({ compact: collectionName }); }); 

从Mongo的2.8版本开始,您可以使用压缩 。 用WiredTiger引擎,你将有3个级别的压缩,mmap(默认在2.6不提供压缩):

  • 没有
  • 活泼 (默认)
  • zlib的

以下是您可以为16 GB数据保存多less空间的示例:

在这里输入图像描述

数据来自这篇文章。

基于StorageEngine,我们需要解决两个方面的问题。

1. MMAP()引擎:

命令: db.repairDatabase()

注: repairDatabase需要可用磁盘空间等于您当前数据集的大小加上2千兆字节。 如果容纳dbpath的卷缺less足够的空间,则可以安装单独的卷并将其用于修复。 在为repairDatabase安装单独的卷时,必须从命令行运行repairDatabase,并使用–repairpath开关指定要在其中存储临时修复文件的文件夹。 例如:想象数据库大小是120 GB,意味着(120 * 2)+2 = 242 GB所需的硬盘空间。

另一种方法你明智的收集,命令: db.runCommand({compact:'collectionName'})

2. WiredTiger:它自动解决它。

如果从集合中删除大量数据并且集合从不将新的文档的已删除空间用到该空间,则需要将该空间返回给操作系统,以便其可以被其他数据库或集合使用。 您将需要运行紧凑或修复操作,以便对磁盘空间进行碎片整理并重新获得可用空间。

压缩过程的行为依赖于MongoDB引擎,如下所示

 db.runCommand({compact: collection-name }) 

MMAPv1

压缩操作对数据文件和索引进行碎片整理。 但是,它不会释放操作系统的空间。 该操作对碎片整理仍然有用,并为MongoDB创build更多的连续空间供重用。 但是,当可用磁盘空间非常小时,这是没有用的。

在压缩操作过程中需要额外的磁盘空间达到2GB。

压缩操作期间将保持数据库级别的locking。

WiredTiger

WiredTiger引擎默认提供压缩比MMAPv1消耗更less的磁盘空间。

紧凑的进程释放到操作系统的可用空间。 运行紧凑操作需要最小的磁盘空间。 WiredTiger还会阻止数据库上的所有操作,因为它需要数据库级locking。

对于MMAPv1引擎,紧凑型操作系统不会返回空间。 您需要运行修复操作来释放未使用的空间。

 db.runCommand({repairDatabase: 1}) 

你可以在这里find关于紧凑操作的详细信息

Mongodb 3.0和更高版本有一个新的存储引擎 – WiredTiger。 在我的情况下,交换引擎将磁盘使用量从100 Gb减less到25 Gb。

在MongoDB的空间回收方面出现了一些相当混乱的情况,一些推荐的做法在某些部署types中是非常危险的。 更多细节如下:

TL; DR repairDatabase尝试从尝试从磁盘损坏中恢复的独立MongoDB部署中抢救数据。 如果它恢复了空间,那纯粹是一个副作用 。 恢复空间不应该是运行repairDatabase的主要考虑repairDatabase

恢复独立节点中的空间

WiredTiger:对于带有WiredTiger的独立节点,运行compact会释放操作系统的空间,但需要注意的一点是:MongoDB 3.0.x上的WiredTiger上的compact命令受到以下bug的影响: SERVER-21833在MongoDB 3.2.3中修复。 在此版本之前,WiredTiger上的compact系统可能会默默地失败。

MMAPv1:由于MMAPv1的工作方式,没有使用MMAPv1存储引擎恢复空间的安全且受支持的方法。 compact的MMAPv1会对数据文件进行碎片整理,可能会为新文件提供更多空间,但不会释放空间回OS。

如果你完全理解这个有潜在危险的命令的后果(见下面),你可以运行repairDatabase ,因为repairDatabase本质上是通过丢弃损坏的文档来重写整个数据库。 作为一个副作用,这将创build新的MMAPv1数据文件没有任何碎片,并释放空间回操作系统。

对于不太冒险的方法,在MMAPv1部署中运行mongodumpmongorestore也是可能的,这取决于部署的大小。

恢复副本集中的空间

对于副本集configuration,恢复空间的最佳和最安全的方法是对WiredTiger和MMAPv1执行初始同步 。

如果您需要从集合中的所有节点恢复空间,则可以执行滚动初始同步。 也就是说,在每个辅助节点上执行初始同步,然后最终降级主节点并对其执行初始同步。 滚动初始同步方法是执行副本集维护最安全的方法,也不涉及停机时间作为奖励。

请注意,滚动初始同步的可行性还取决于部署的大小。 对于非常大的部署,执行初始同步可能不太可行,因此您的select会受到一些限制。 如果使用WiredTiger,您可以从一组中取出一个辅助,将其作为独立启动,在其上运行compact ,然后重新join到集合中。

关于repairDatabase

请不要在副本集节点上运行repairDatabase 。 这是非常危险的,正如repairDatabase页面中所提到的,下面会详细介绍。

名称repairDatabase有点误导,因为该命令不会尝试修复任何内容。 该命令旨在用于独立节点上的磁盘损坏,这可能会导致损坏的文档。

repairDatabase命令可以更准确地描述为“救助数据库”。 也就是说,它通过丢弃损坏的文档来重新创build数据库,试图使数据库进入一种状态,在这种状态下,您可以启动它并从中恢复完整的文档。

在MMAPv1部署中,数据库文件的这种重build会释放OS的空间作为副作用 。 释放OS的空间从来不是目的。

repairDatabase副本集上的数据库的后果

在复制集中,MongoDB期望集合中的所有节点都包含相同的数据。 如果在副本集节点上运行repairDatabase ,则有可能节点包含未检测到的损坏,并且repairDatabase将尽职地为您删除损坏的文档。

可以预见的是,这使得该节点包含与该集合的其余部分不同的数据集。 如果更新碰巧碰到单个文档,整个集合可能会崩溃。

更糟糕的是,这种情况完全有可能长期处于hibernate状态,只是突然罢工,没有明显的原因。

数据库文件的大小不能缩小。 在“修复”数据库时,只有mongo服务器才能删除其中的一些文件。 如果大量数据被删除,mongo服务器将在修复过程中“释放”(删除)一些现有文件。

一般来说compact是最好的修复数据库。 但是,修复紧凑的一个优点是您可以对整个群集进行修复。 紧凑,你必须login到每个碎片,这是一种讨厌。

当我遇到同样的问题时,我停止了我的mongo服务器,并用命令重新启动它

 mongod --repair 

在执行修复操作之前,您应该检查硬盘上是否有足够的可用空间(最小 – 是数据库的大小)

只有一个方法,我能够做到这一点。 不保证您现有数据的安全性。 尝试自己的风险。

直接删除数据文件并重启mongod。

例如,使用ubuntu(数据的默认path:/ var / lib / mongodb),我有几个文件,名字如下:collection。#。 我collections0,并删除所有其他人。

如果数据库中没有严重的数据,看起来更简单一些。