当我们从MongoDB中删除文档或集合时,MongoDB并不会将已经占用了的磁盘空间释放,它会一直维护已经占用了磁盘空间的数据文件,尽管数据文件中可能存在大大小小的空记录列表(empty record list)。当客户端程序再次插入文档时,MongoDB会从空记录列表中分配存储空间给新文档。那么为了更加有效的使用磁盘空间,我们需要对mongodb的数据文件做碎片整理以及未使用空间的回收。思想无非两种:
1、对原数据进行重组
2、仅将数据复制出来,形成仅数据的完整备份

以下介绍几种常用的实施方法:

1、compact
2、db.repairDatabase()
3、secondary节点重同步
2、db.copyDatabase()

一、compat

官网对该命令的定义:对集合中的所有数据和索引进行重写和碎片整理。

使用方法
use yourdatabase;
db.runCommand({ compact : 'yourCollection' });
注意事项
1、在执行命令前请保证你有比较新的备份
2、在使用MMAPv1存储引擎的MongoDB上compact需要数据文件所在分区至少有2G的空闲空间
3、在使用WiredTiger存储引擎的MongoDB上,compact命令将重写集合和索引,且释放未使用的空间,但使用MMAPv1存储引擎的MongoDB上,该命令只对集合的数据文件进行碎片整理并重新创建其索引。不会释放空间,在使用MMAPv1存储引擎的MongoDB上回收空间,建议使用第三种方法“secondary节点重同步”
4、使用MMAPv1存储引擎的MongoDB中的Capped Collections,是无法被压缩的,但使用WiredTiger存储引擎的MongoDB在执行compact时会进行压缩。
5、在副本集上运行该命令时,要分别在每个节点执行
6、该命令只能在mongod实例上执行,不能再mongos实例上运行。也就是说针对分片集群的compact操作要分别在每个分片节点上执行。
7、一般该命令运行在secondary节点上,在执行时,会强制节点进入RECOVERING状态,RECOVERING状态的实例读写操作将被阻塞
8、再碰到特殊情况要停止运行该命令时,可通过db.currentOp()查询进程信息,然后通过db.killOp()干掉进程
9、compact可能会增加数据文件的总大小和数量,尤其是第一次运行时。但这不会增加总集合使用的磁盘空间,因为存储大小是数据库文件中分配的数据量,而不是文件系统上文件的大小/数量
10、使用MMAPv1存储引擎的MongoDB中的Capped Collections,是无法被压缩的,但使用WiredTiger存储引擎的MongoDB在执行compact时会进行压缩。

二、db.repairDatabase()

官网该命令的定义:通过丢无效或损坏的数据老重建数据库和索引。类似于文件系统修复命令fsck。所以此命令主要是用于修复数据。

使用方法
use yourdatabase;
db.repairDatabase();
注意事项
1、db.repairDatabase()主要用于修复数据。若你拥有数据的完整副本,且有权限访问,请使用第三种方法“secondary节点重同步”
2、在执行命令前请保证你有比较新的备份
3、此命令会完全阻塞数据库的读写,谨慎操作
4、此命令执行需要数据文件所在位置有等同于所有数据文件大小总和的空闲空间再加上2G
5、在使用MMAPv1存储引擎的secondary节点上执行该命令可以压缩集合数据
6、在使用WiredTiger存储引擎的MongoDB库上执行不会有压缩的效果
7、再碰到特殊情况要停止运行该命令时,可通过db.currentOp()查询进程信息,然后通过db.killOp()干掉进程
8、非常消耗时间

三、secondary节点重同步

主要思想就是:删除secondary节点中指定数据,使之与primary重新开始数据同步。当副本集成员数据太过陈旧,也可以使用重新同步。数据的重新同步与直接复制数据文件不同,MongoDB会只同步数据,因此重同步完成后的数据文件是没有空集合的,以此实现了磁盘空间的回收。

使用方法

首先必须确保数据有完整的备份。

1、若是primary节点,先强制将之变为secondary节点,否则跳过此步骤:rs.stepdown(120);
2、然后在primary上删除secondary节点:rs.remove("IP:port");
3、删除secondary节点dbpath下的所有文件。
4、将节点重新加入集群,然后使之自动进行数据的同步:rs.add("IP:port");
5、等数据同步完成后,循环1-4的步骤可以将集群中所有节点的磁盘空间释放针对一些特殊情况,不能下线secondary节点的,可以新增一个节点到副本集中,然后secondary就自动开始数据的同步了。
总的来说,重同步的方法是比较好的,第一基本不会阻塞副本集的读写,第二消耗的时间相对前两种比较短

四、db.copyDatabase()

mongodb还支持在线复制数据:db.copyDatabase("from","to","IP:port"),此种方法也能释放空间,因为db.copyDatabase复制的数据,而不是表示在磁盘中的数据文件。但,该命令在4.0版本起被弃用;3.x版本还能继续使用
如:db.copyDatabase("sourceDB","DistDB");将源库sourceDB。拷贝为DistDB。当然,该命令支持远程复制。
该命令的完整语法为:
db.copyDatabase(<源数据库名称>, <目标数据库名称>, <源mongodb的IP:port>, <源数据库连接需要的账户>,<密码>, <mechanism>)以上:命令必须在目标数据库服务器上执行。若源数据库与目标数据库存在于一个MongoDB服务器,<源mongodb的IP:port>, <源数据库连接需要的账户>,<密码>都可省略。<mechanism>是身份验证类型,可选的。
注意事项
1、db.copyDatabase()不会阻塞源数据库和目标数据库数据的读写,因此可能会出现两份数据不一致的情况
2、db.copyDatabase()复制索引数据会锁定数据库,此操作也会对其他数据库产生影响
3、db.copyDatabase()不要在mongos实例中使用
4、db.copyDatabase()不要用于复制包含分片集合的数据库
5、在4.0版中更改:db.copyDatabase()仅支持SCRAM进行身份验证fromhost,<mechanism>选项。
6、某些不同版本的MongoDB间不支持此种复制方法,详见链接:https://docs.mongodb.com/manual/reference/method/db.copyDatabase/

除此之外,还有一些方法,像使用导入/导出的方法(mongodump/mongorestore),这种方法在数据量非常大的情况是不适用的,因为导入导出的方法使用的全量的形式,要保证有足够的空闲空间来存放导入的数据。

MongoDB如何释放空闲空间?相关推荐

  1. 操作系统——可变分区空闲空间管理

    目录 一. 关键问题:如何管理空闲空间 二. 假设 三 . 底层机制 1. 分割 2. 合并 3. 追踪分配内存大小 4. 如何在空闲内存内部建立列表 四. 分配算法 1. 最优匹配(best fit ...

  2. Windows 8.1下释放磁盘空间的指南

    This is an "updated for Windows 8.1" version of my popular original article Guide to Freei ...

  3. mysql删除数据后释放磁盘空间

    drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM : truncate table table_name立刻释放磁盘空间 ,不管是 Innodb和My ...

  4. Linux中如何释放交换空间swap

    一.Linux内存机制简单介绍 直接从物理内存读写数据要比从硬盘读写数据要快的多(硬盘磁道寻址),因此,我们希望所有数据的读写都在内存完成,但是内存大小是有限的,并且内存价格高于硬盘价格,于是就有了物 ...

  5. mysql释放表空间

    公司用的阿里云的RDS数据库 经常磁盘空间超过80% 后来发现有一个表message数据就30万,却占用了65G空间,非常不正常. 后来发现有一个命令,可以释放表空间. 命令如下 optimize t ...

  6. mongodb 查看数据库和空间大小

    mongodb 查看数据库和空间大小 单位是M db.stats(1048576); 单位是G db.stats(1073741824); posted on 2019-02-22 17:36 luo ...

  7. C++ string清空并释放内存空间的两种方法(shrink_to_fit()、swap())

    说明 在STL中 vector和string 是比较特殊的,clear()之后是不会释放内存空间的,也就是size()会清零,但capacity()不会改变,需要手动去释放,说明 clear() 没有 ...

  8. 一个释放临时表空间的实例

    释放临时表空间实例 临时表空间 临时表空间作用 Oracle临时表空间主要用来做查询和存放一些缓冲区数据.临时表空间消耗的主要原因是需要对查询的中间结果进行排序. 重启数据库可以释放临时表空间,如果不 ...

  9. Domino下邮箱用户数据库限额自助释放物理空间

    Domino下邮箱用户数据库限额自助释放物理空间 说到Domino邮箱用户数据库,大家都知道,每个邮箱用户都会有一个自己标识的.nsf数据库:这样从管理员管理角度上非常方便管理,及时用户的数据库损坏了 ...

最新文章

  1. 祝贺自己itpub和csdn双双荣获专家博客标题
  2. httpclient解析https网页
  3. python 自定义模块的发布和安装
  4. hough变换直线检测_python+opencv实现霍夫变换检测直线
  5. 磁盘分区20191017
  6. [转载] python无法从nltk中调取文本 from nltk.book import *
  7. java 新手入门电子书_java基础入门电子版pdf下载-java基础入门电子版百度云pdf高清版-东坡下载...
  8. Win32 Application和Win32 Console Application区别
  9. mysql nlssort_Oracle中文排序 NLSSORT
  10. 小程序软件有必要申请软件著作权登记么?
  11. from collections import Counter计数器
  12. wd移动硬盘不能识别_wd移动硬盘无法识别
  13. 老飞飞秒进卡尔贝西龙洞不用走路的方法
  14. android wifi热点setting
  15. Kafka 2.8.0 学习
  16. The NTVDM CPU has encountered an illegal instruction. CS:0006 IP:130a ....
  17. stm32wb55 基于rtt的ble sample制作过程
  18. 北航软件能力培养启发和下一步工作
  19. 建立强大的verilog编写环境
  20. 英语——形容词(一)

热门文章

  1. mac memcached_如何在Mac OS上安装Memcached Server
  2. jmc线程转储_Java线程转储– VisualVM,jstack,kill -3,jcmd
  3. json 例子_json-简单的例子
  4. tf.train.Example的用法
  5. C++面试题:内存的分配方式有几种?
  6. 作为一个产品经理,产品文档该怎样写
  7. 欧几里得算法及扩展欧几里得算法简单解释
  8. IEnumerable.Select和SelectMany的区别
  9. 第三方平台也能为未微信认证的订阅号调用自定义菜单接口和素材管理接口
  10. 从maya中 导入物体 到Uniyt3D 规范 整理