MongoDB之compact操做详解

摘要: compact操做步骤不少,可是能够有效减小磁盘使用量。算法

MongoDB与磁盘

Fundebug处理的数据愈来愈多,这致使MongoDB的磁盘使用量愈来愈多,增加也愈来愈快。因而,我开始定时删除过时数据,优化算法减小冗余数据。可是,我发现,单纯删除文档不能减小MongoDB磁盘使用量。这是为何呢?下面是官方文档的解释:mongodb

对于WiredTiger存储引擎(mongodb 3.2以后默认使用):How do I reclaim disk space in WiredTiger?docker

The WiredTiger storage engine maintains lists of empty records in data files as it deletes documents. This space can be reused by WiredTiger, but will not be returned to the operating system unless under very specific circumstances.数据库

也就是说,被删除的文档所占用的磁盘空间仍然由MongoDB保留,不会释放。对于旧版MongoDB的MMAPv1存储引擎,这一点也是同样的。这样作无可厚非,由于数据库将会不断存储新的文档,它们能够利用以前保留的磁盘空间。bash

可是,若是你删除了不少文档,须要MongoDB释放磁盘空间,应该如何作呢?正如文档所述,对于WiredTiger存储引擎,咱们可使用compact操做来实现。less

To allow the WiredTiger storage engine to release this empty space to the operating system, you can de-fragment your data file. This can be achieved using the compact command.性能

关于compact操做

compact操做会从新整理碎片化的磁盘,释放多余的空间。优化

Rewrites and defragments all data and indexes in a collection. On WiredTiger databases, this command will release unneeded disk space to the operating system.this

关于compact操做,我列了几个简单的Q&A。spa

  • compact是否会阻塞数据库读写?会!所以不能在高峰期进行compact操做;对于复制集,应该对每一个节点依次进行compact操做。
  • compact是否能够释放磁盘空间?对于WiredTiger,是能够的;可是对于WiredTiger存储引擎,并不会,多余的磁盘空间仍然会保留给MongoDB。
  • compact操做是否会占用额外的磁盘空间?根据个人观察,基本上不会。
  • paddingFactor应该设为多少?我设置的值是1.1,这样能够为每一个文档留一些多余空间,提升修改性能。这个值能够根据实际须要进行设置。
  • compact操做须要多少时间?一个400G的复制集节点,我花了不到1个小时。这样时间应该与数据量大小有关。
  • compact操做效果怎么样?减小了接近50%的磁盘空间,这个大小应该与被删除的文档数量有关。

compact操做步骤

因为compact操做会阻塞MongoDB的读写操做,所以应该对每一个节点依次进行操做。另外,MongoDB复制集的标准维护流程是将Secodary节点暂定,使用单独的端口启动独立的mongo实例进行操做,这样能够复制集彻底隔离。

咱们Fundebug的MongoDB集群运行在Docker中,所以操做步骤稍微简单一些,能够为你们提供参考。

Secondary节点

  • 关闭mongodb容器
sudo docker stop mongo
复制代码
  • 启动独立的临时mongodb容器
sudo docker run -it -d -p 37017:27017 -v /data/db:/data/db --name mongo_tmp mongo:3.2
复制代码
  • 执行compact命令
mongo 127.0.0.1:37017
db.runCommand( { compact : 'events',paddingFactor: 1.1 } )
复制代码
  • 重启mongodb节点
sudo docker rm -f mongo_tmp
sudo docker start mongo
复制代码

Primary节点

  • 将Primary节点变为Secondary节点
rs.stepDown()
复制代码
  • 按照secondary节点进行操做

参考

相关文章
相关标签/搜索