当我们从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. MongoDB repairDatabase 释放磁盘空间

    repairDatabase是官方文档中认为唯一可以回收硬盘空间的方法. repairDatabase is the appropriate and the only way to reclaim d ...

  2. mongodb拷贝数据库copyDatabase()。实现释放磁盘空间的方法。

    下面我们一起来看看关于mongodb拷贝数据库copyDatabase().实现释放磁盘空间的方法,希望文章对各位同学会有所帮助. db.copyDatabase("from",& ...

  3. (转) Delete/Truncate删除,释放表空间、降低高水位线、resize释放磁盘空间相关优化

    硬盘空间不足,打算删除数据库中的多余数据,但删除数据后,硬盘硬盘空间不能释放.[delete后用:alter table table_name move    truncate后用:alter tab ...

  4. 【转】利用optimize、存储过程和系统表对mysql数据库表进行批量碎片清理释放表空间

    本文收集于本人的笔记本,由于找不到原文出处.在此省略,如哪位知道可以联系我加上. 核心是利用mysql系统表和“optimize table 表名”命令,对mysql数据表进行空间的释放.由于dele ...

  5. oracle 删除表、表空间、用户时,如何释放磁盘空间

    truncate table tablename DROP STORAGE; drop 执行drop table xx 语句drop后的表被放在回收站(user_recyclebin)里,而不是直接删 ...

  6. Oracle中关于清除数据和释放表空间

    一.表的重命名 flashback table test2 to before drop rename to test3;--[to test3]将表重命名 drop table test3 purg ...

  7. Mysql InnoDB彻底释放磁盘空间

    Innodb数据库对于已经删除的数据只是标记为删除,并不真正释放所占用的磁盘空间,这就导致InnoDB数据库文件不断增长. 如果需要彻底释放磁盘空间,则需要先导出数据,然后删除数据文件,最后导入数据. ...

  8. [记录]一则清理MySQL大表以释放磁盘空间的案例

    一则清理MySQL大表以释放磁盘空间的案例 一.基本情况: 1.dbtest库554G,先清理st_online_time_away_ds(37G)表的数据,保留半年的数据: 1)删除的数据:sele ...

  9. [转]oracle在删除表\表空间\用户时,如何释放磁盘空间

    一.drop表 执行drop table xx 语句 drop后的表被放在回收站(user_recyclebin)里,而不是直接删除掉.这样,回收站里的表信息就可以被恢复,或彻底清除. 通过查询回收站 ...

随机推荐

  1. centos中从源程序升级python方法

    http://www.cnblogs.com/sky20081816/p/3441920.html 1 .wget http://python.org/ftp/python/2.7.3/Python- ...

  2. 代码分析工具推荐Understand

    之前看ogitor ,第一次看到那么多代码~~不知道从哪里下手,而且好多东西都不会Ogre什么的都不是很清楚,对ogitor的代码结构的了解就更不用提了.晕头转向的 不知道从哪里下手,一点点的看起来好 ...

  3. nginx的开机自启、server命令启动、nginx.conf配置

    1.将Nginx设置为开机自动启动 a.当上面6步完成之后,说明安装已经完全成功了,但是每次开机我们面临的一个问题,就是每次都要执行命令(1: cd /usr/local/nginx/sbin/   ...

  4. The FLARE On Challenge

    上周才开始做这个CTF,用一周左右的时间完成了全部7道题.算是为即将到来的找工作进行热身和学习,下面记录一下遇到的问题和学到的东西,具体的解题过程就不详细描述了. challenge1 这道题用IDA ...

  5. photoshopcs6破解补丁用来干嘛的

    photoshopcs6破解补丁为 Adobe CS6 系列软件通用破解补丁,亲测可用,终于能用了不再出现那个烦人的购买页面了,cs6破解补丁解压后得到32和64两个文件夹,根据自己的系统类型选择,6 ...

  6. oracle中的分区表

    oracle中的分区表在系统中使用的频率不小,在一些数据量大的系统中更是频繁出现. 提到分区表,首先就要理解下什么是分区.其实所谓的分区简单来说就是分区域,分区表就是将一张表分区域存放. 那么分区域中 ...

  7. C#配置IIS搭建网站的工具类

    public class IISWorker { public static string HostName = "localhost"; /// <summary> ...

  8. create-react-app部署到GitHub Pages时报错:Failed to get remote。origin.url

    最近使用create-react-app脚手架开发了一个私人博客:点击跳转,在部署到GitHub Pages的时候报了一个错误,具体如下: 在create-react-app的GitHub库的issu ...

  9. excel 在web导入到数据库的操作方法

    这个操作的大致步骤是把本地文件存入到服务器端,然后再读取服务端的文件并且使用NPOI这个第三方的插件去读取文件导入到数据库批量插入需要注意的是,前端需要使用form包裹type=file的文件标签,并 ...

  10. arcgis server 9.3 查看地图服务时出现"No Content"错误

    问题描述: 使用ArcGIS Server Manager的Add new service功能发布一个服务.然后启动服务 用浏览器访问该服务的地址http://localhost/ArcGIS/ser ...