我有一个曾经很大(> 3GB)的MongoDB数据库.从那时起,文档已被删除,我希望数据库文件的大小相应减少.
但是由于MongoDB保留了分配的空间,因此文件仍然很大.
我在这里和那里读到,admin命令mongod --repair
用于释放未使用的空间,但我没有足够的空间来运行此命令.
你知道我可以释放未使用空间的方法吗?
更新:使用compact
命令和 WiredTiger看起来实际上将额外的磁盘空间释放到操作系统.
更新:从v1.9 +开始,有一个compact
命令.
该命令将"在线"执行压缩.它仍然需要一些额外的空间,但不是那么多.
MongoDB通过以下方式压缩文件:
将文件复制到新位置
循环遍历文档并重新排序/重新解决它们
用新文件替换原始文件
您可以通过运行mongod --repair
或直接连接和运行来"压缩" db.repairDatabase()
.
在任何一种情况下,您都需要在某处复制文件的空间.现在我不知道为什么你没有足够的空间来执行压缩,但是,如果你有另一台有更多空间的计算机,你确实有一些选择.
将数据库导出到安装了Mongo的另一台计算机(使用mongoexport
),然后您可以导入同一个数据库(使用mongoimport
).这将导致更加压缩的新数据库.现在你可以mongod
用新的数据库文件停止原来的替换,你就可以了.
停止当前的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命令不需要双磁盘空间来完成它的工作.它在工作时需要少量的额外空间.另外,compact更快."
压缩当前数据库中的所有集合
db.getCollectionNames().forEach(function (collectionName) { print('Compacting: ' + collectionName); db.runCommand({ compact: collectionName }); });
如果需要运行完整修复,请使用该repairpath
选项.将其指向具有更多可用空间的磁盘.
例如,在我的Mac上我使用过:
mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair
更新:根据MongoDB核心服务器--nojournal
故障单4266,您可能需要添加以避免错误:
mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal
从2.8版本的Mongo开始,您可以使用压缩.使用WiredTiger引擎有3个级别的压缩,mmap(默认情况下2.6不提供压缩):
没有
snappy(默认情况下)
zlib的
下面是一个示例,说明您可以为16 GB数据节省多少空间:
数据取自本文章.
我们需要基于StorageEngine解决2种方法.
1. MMAP()引擎:
命令:db.repairDatabase()
注意: repairDatabase需要的可用磁盘空间等于当前数据集的大小加上2千兆字节.如果保存dbpath的卷缺少足够的空间,则可以装入单独的卷并将其用于修复.为repairDatabase安装单独的卷时,必须从命令行运行repairDatabase,并使用--repairpath开关指定用于存储临时修复文件的文件夹.例如:想象一下DB大小是120 GB意味着,(120*2)+2 = 242 GB所需的硬盘空间.
另一种方法是收集明智,命令: db.runCommand({compact:'collectionName'})
2. WiredTiger: 它自动解决它自己.
如果从集合中删除了大量数据,并且该集合从未将删除的空间用于新文档,则需要将该空间返回给操作系统,以便其他数据库或集合可以使用该空间。您将需要执行压缩或修复操作以对磁盘空间进行碎片整理并重新获得可用的可用空间。
压缩过程的行为取决于MongoDB引擎,如下所示
db.runCommand({compact: collection-name })
MMAPv1
压缩操作对数据文件和索引进行碎片整理。但是,它不会为操作系统释放空间。该操作对于碎片整理和创建更多连续空间供MongoDB重用仍然很有用。但是,当可用磁盘空间非常低时,它没有用。
压缩操作期间需要最多2GB的额外磁盘空间。
在压缩操作期间,将保持数据库级别的锁定。
有线老虎
默认情况下,WiredTiger引擎提供压缩,该压缩比MMAPv1消耗更少的磁盘空间。
紧凑的过程将可用空间释放给操作系统。运行压缩操作需要最少的磁盘空间。WiredTiger还需要对数据库进行级别锁定,从而阻止了对数据库的所有操作。
对于MMAPv1引擎,压缩不会将空间返回给操作系统。您需要运行修复操作以释放未使用的空间。
db.runCommand({repairDatabase: 1})
在MongoDB中,对于空间回收存在一些相当大的困惑,并且在某些部署类型中,某些建议的做法非常危险。以下是更多详细信息:
TL; DR repairDatabase
尝试从试图从磁盘损坏中恢复的独立MongoDB部署中挽救数据。如果它恢复了空间,那纯粹是副作用。恢复空间永远不是运行的主要考虑因素repairDatabase
。
WiredTiger:对于具有WiredTiger的独立节点,运行compact
将释放空间到操作系统,但有一个警告:compact
在MongoDB 3.0.x上的WiredTiger上的命令受到以下错误的影响:SERVER-21833,该错误已在MongoDB 3.2.3中修复。在此版本之前,compact
WiredTiger可能会静默失败。
MMAPv1:由于MMAPv1的工作方式,没有使用MMAPv1存储引擎来恢复空间的安全且受支持的方法。compact
MMAPv1中的版本将对数据文件进行碎片整理,从而有可能为新文档提供更多空间,但不会将空间释放回操作系统。
您可能能够运行repairDatabase
,如果你完全了解这种后果的潜在危险的命令(见下文),因为repairDatabase
基本上是通过丢弃损坏的文件重写整个数据库。副作用是,这将创建新的MMAPv1数据文件,而不会对其造成任何碎片,并将空间释放回操作系统。
对于冒险性较低的方法,根据您的部署规模,可以在MMAPv1部署中运行mongodump
,mongorestore
也可以使其运行。
对于副本集配置,恢复空间的最佳和最安全的方法是对WiredTiger和MMAPv1 执行初始同步。
如果需要从集合中的所有节点恢复空间,则可以执行滚动初始同步。也就是说,在最终退出主节点并对其进行初始同步之前,请对每个辅助节点执行初始同步。滚动初始同步方法是执行副本集维护的最安全方法,并且不涉及停机时间。
请注意,进行滚动初始同步的可行性还取决于部署的大小。对于超大型部署,进行初始同步可能不可行,因此您的选择受到更多限制。如果使用WiredTiger,则可以从集合中取出一个辅助副本,将其作为独立副本启动,compact
在其上运行,然后将其重新加入到集合中。
repairDatabase
请不要repairDatabase
在副本集节点上运行。如repairDatabase页面中所述,并在下面进行更详细的描述,这是非常危险的。
名称repairDatabase
有点误导,因为该命令不会尝试修复任何内容。该命令旨在用于独立节点上的磁盘损坏,这可能会导致文档损坏。
该repairDatabase
命令可以更准确地描述为“救助数据库”。也就是说,它通过丢弃损坏的文档来重新创建数据库,以使数据库进入可以启动数据库并从中回收完整文档的状态。
在MMAPv1部署中,这种数据库文件的重建为OS释放了空间,这是一个副作用。向操作系统释放空间从来都不是目的。
repairDatabase
副本集上的后果在副本集中,MongoDB希望该集中的所有节点都包含相同的数据。如果您repairDatabase
在副本集节点上运行,则该节点有可能包含未检测到的损坏,并repairDatabase
会忠实地为您删除损坏的文档。
可以预见,这将使该节点包含与该集合其余部分不同的数据集。如果有更新发生在单个文档上,那么整个文档集可能会崩溃。
更糟糕的是,这种情况很可能长时间处于休眠状态,只是突然发作而没有明显的原因。