我有一个曾经很大的MongoDB数据库(> 3GB)。从那时起,文档已被删除,我期望数据库文件的大小相应减少。
但是由于MongoDB保留分配的空间,因此文件仍然很大。
我在这里和那里读到,admin命令mongod --repair
用于释放未使用的空间,但是磁盘上没有足够的空间来运行此命令。
您知道我可以释放未使用空间的方法吗?
我有一个曾经很大的MongoDB数据库(> 3GB)。从那时起,文档已被删除,我期望数据库文件的大小相应减少。
但是由于MongoDB保留分配的空间,因此文件仍然很大。
我在这里和那里读到,admin命令mongod --repair
用于释放未使用的空间,但是磁盘上没有足够的空间来运行此命令。
您知道我可以释放未使用空间的方法吗?
Answers:
更新:使用compact
命令和 WiredTiger,看起来多余的磁盘空间实际上将释放到OS。
更新:从v1.9 +开始,有一个compact
命令。
该命令将执行“在线压缩”。它仍然需要一些额外的空间,但并不需要那么多。
MongoDB通过以下方式压缩文件:
您可以通过运行mongod --repair
或通过直接连接和运行来执行此“压缩”操作db.repairDatabase()
。
无论哪种情况,您都需要在某个地方复制文件。现在,我不知道为什么您没有足够的空间来执行压缩,但是,如果您有一台具有更多空间的计算机,您确实可以选择。
mongoexport
),然后可以导入同一数据库(使用mongoimport
)。这将导致新数据库的压缩程度更高。现在,您可以停止mongod
使用新的数据库文件进行原始替换了,一切顺利。当前没有使用Mongo进行“紧凑压缩”的好方法。而且Mongo绝对可以占用很多空间。
目前最好的压缩策略是运行主从设置。然后,您可以压缩从站,让它赶上并切换它们。我知道还是有点毛。也许Mongo团队会提出更好的就地压实,但我认为这并不在他们的榜单上。当前假定驱动器空间便宜(通常是便宜的)。
compact
,他至少可以保留现有文件。我同意,这不是一个完整的解决方案,但它是逐步的改进。
我遇到了同样的问题,只需在命令行中执行此操作即可解决:
mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename
mongorestore --db databasename dump/databasename
看来Mongo v1.9 +已支持紧凑版!
> db.runCommand( { compact : 'mycollectionname' } )
请参阅此处的文档:http : //docs.mongodb.org/manual/reference/command/compact/
“与repairDatabase不同,compact命令不需要双重磁盘空间来完成其工作。它在工作时确实需要少量额外的空间。此外,compact更快。”
repairDatabase
而不是通过实现的compact
。compact
不会释放空间,只会对已用完的空间进行碎片整理,而不会减少空间。
compact
将回收空间。
如果您需要进行全面维修,请使用该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
我们需要基于StorageEngine解决2种方法。
1. MMAP()引擎:
命令:db.repairDatabase()
注意: repairDatabase需要的可用磁盘空间等于您当前数据集的大小再加上2 GB。如果保存dbpath的卷缺少足够的空间,则可以装入一个单独的卷并将其用于修复。为修复数据库装入单独的卷时,必须从命令行运行repairDatabase并使用--repairpath开关指定用于存储临时修复文件的文件夹。例如:假设DB大小为120 GB,则意味着(120 * 2)+2 = 242 GB硬盘空间。
另一种明智的收集方式,命令: db.runCommand({compact:'collectionName'})
2. WiredTiger: 它会自动自行解决。
在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
会忠实地为您删除损坏的文档。
可以预见,这将使该节点包含与该集合其余部分不同的数据集。如果有更新发生在单个文档上,则整个文档集可能会崩溃。
更糟的是,这种情况很可能长时间处于休眠状态,只是突然发作而没有明显的原因。
如果从集合中删除了大量数据,并且该集合从未将删除的空间用于新文档,则需要将该空间返回给操作系统,以便其他数据库或集合可以使用该空间。您将需要执行压缩或修复操作以对磁盘空间进行碎片整理并重新获得可用的可用空间。
压缩过程的行为取决于MongoDB引擎,如下所示
db.runCommand({compact: collection-name })
MMAPv1
压缩操作对数据文件和索引进行碎片整理。但是,它不会为操作系统释放空间。该操作对于碎片整理和创建更多连续空间供MongoDB重用仍然很有用。但是,当可用磁盘空间非常低时,它没有用。
压缩操作期间需要最多2GB的额外磁盘空间。
在压缩操作期间,将保持数据库级别的锁定。
有线老虎
默认情况下,WiredTiger引擎提供压缩,该压缩比MMAPv1占用更少的磁盘空间。
紧凑的过程将可用空间释放给操作系统。运行压缩操作需要最少的磁盘空间。WiredTiger还需要对数据库进行级别锁定,从而阻止了对数据库的所有操作。
对于MMAPv1引擎,压缩不会将空间返回给操作系统。您需要运行修复操作以释放未使用的空间。
db.runCommand({repairDatabase: 1})
当我遇到同样的问题时,我停止了mongo服务器,然后使用命令再次启动它
mongod --repair
在运行修复操作之前,您应该检查硬盘上是否有足够的可用空间(最小值-是数据库的大小)
对于独立模式,您可以使用紧凑型或维修型,
对于分片群集或副本集,以我的经验,在主数据库上运行压缩,然后在辅助数据库上压缩之后,主数据库的大小减小了,但辅助数据库没有减小。您可能想要执行重新同步成员以减小辅助数据库的大小。通过这样做,您可能会发现辅助数据库的大小甚至比主数据库减小了很多,我猜这个compact命令并没有真正压缩集合。因此,我最终切换了副本集的主副本和辅助副本,并再次进行了重新同步成员。
我的结论是,减少分片/副本集大小的最佳方法是执行重新同步成员,切换主从节点和再次重新同步。
如果是分片群集,建议不要使用mongoDB -repair。
如果使用副本集分片群集,请使用紧凑命令,它将重写和整理所有集合的所有数据和索引文件。 句法:
db.runCommand( { compact : "collection_name" } )
与force:true一起使用时,compact在副本集的主副本上运行。
例如 db.runCommand ( { command : "collection_name", force : true } )
需要考虑的其他要点:-它阻止了操作。因此建议在维护窗口中执行。-如果副本集在不同的服务器上运行,则需要分别在每个成员上执行-对于分片群集,压缩需要在每个分片成员上单独执行。无法针对mongos实例执行。
这是我能够做到的一种方式。无法保证现有数据的安全性。尝试自己承担风险。
直接删除数据文件,然后重新启动mongod。
例如,使用ubuntu(数据的默认路径:/ var / lib / mongodb),我有几个文件,其名称类似于:collection。#。我保留了collection.0并删除了所有其他集合。
如果您在数据库中没有大量数据,似乎是一种更简单的方法。