当我们从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. WPF控件相对位置解析

    WPF控件相对位置的获取方法是比较简单的.对于初学者来说,掌握这一技巧的应用,可以帮助以后对WPF的深入学习,而且在实际使用中,这是一个非常常用的方法. 我们知道WPF有着比较灵活的布局方式,关于某个 ...

  2. Java程序中解决数据库超时与死锁

    Java程序中解决数据库超时与死锁 2011-06-07 11:09 佚名 帮考网 字号:T | T   Java程序中解决数据库超时与死锁,每个使用关系型数据库的程序都可能遇到数据死锁或不可用的情况 ...

  3. ASP.NET常用内置对象之——Server

    简介 Server对象是HttpServerUtility的一个实例,也是上下文对象context的一个属性,提供用于处理Web请求的Helper方法. 常用成员 一.Server.MapPath() ...

  4. 关于NativeEvent的处理

    nativeEvent(const QByteArray &eventType, void *message, long *result){ chASSERT(message != NULL) ...

  5. C与C++混编

    了解一下C与C++如何合作,gcc和g++编译出来的东西有什么区别. 工具使用 objdump是个好工具,可以用于查看.o文件的内容,也可以查看可执行文件的内容. 查看符号表 objdump -t f ...

  6. python 爬虫网络图片中遇到的问题总结

    1.只导入了import urllib,读取网页的时候page =urllib.urlopen(url),提示 “module’ object has no attribute ’urlopen’”, ...

  7. Event Driven Architecture

    在微服务中使用领域事件   稍微回想一下计算机硬件的工作原理我们便不难发现,整个计算机的工作过程其实就是一个对事件的处理过程.当你点击鼠标.敲击键盘或者插上U盘时,计算机便以中断的形式处理各种外部事件 ...

  8. UVA11987 【Almost Union-Find】

    这是一道神奇的题目,我调了大概一天多吧 首先hack一下翻译,操作3并没有要求查询后从其所在集合里删除该元素 于是我们来看一下这三个操作 第一个合并属于并查集的常规操作 第三个操作加权并查集也是可以解 ...

  9. webpack导学

    随着前端工程越来越复杂,单独建几个文件写业务代码,这样的方式已经无法保证项目的可维护性了. 所以我们就想把不同的逻辑拆成模块,然后分开引入这些模块,每个模块自己做自己的事情,这样就可以保证项目的可维护 ...

  10. BZOJ 3744: Gty的妹子序列 【分块 + 树状数组 + 主席树】

    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=3744 3744: Gty的妹子序列 Time Limit: 20 Sec  Memory ...