MongoDB释放空闲空间的几种常用方法

前言

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

1、对原数据进行重组

2、仅将数据复制出来,形成仅数据的完整备份

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

1、compact

2、db.repairDatabase()

3、secondary节点重同步

4、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),这种方法在数据量非常大的情况是不适用的,因为导入导出的方法使用的全量的形式,要保证有足够的空闲空间来存放导入的数据。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 巧妙的利用Mongodb做地理空间查询

    MongoDB是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. 在移动开发中,经常会用到定位的功能,例如美团.饿了么.猫眼电影等的app,都是使用了移动端定位,然后查找出自己地理位置附近的一些服务.信息. 地理位置索引是MongoDB早已被用户所熟知的特性,其球面(Spherical)和平面(Flat)两种模式,提供了丰富的地址位置的表示方式,如2d.2dsphere和GeoJSON等,对于移动App,如地图软件.打车软件.外卖软件,M

  • 详解清除MongoDB所占用的多余的磁盘空间的方法

    首先一点就是mongodb 不会释放已经占用的硬盘空间,即使drop collection也不行,除非drop database.如果一个db曾经有大量的数据一段时间后又删除的话,硬盘空间就是一个问题,如何收回被mongdodb占用的多余空间?方法有两种 1. dump & restore mongodump -d databasename -o /path/to/dump_dir echo 'db.dropDatabase()' | mongo <databasename> mong

  • mongodb 集群重构和释放磁盘空间实例详解

    MongoDB集群重构,释放磁盘空间 由于mongodb删除了一部分数据后,不会回收相应的磁盘空间,所以这里通过重建数据目录的方式释放磁盘空间. 一 实验环境 配置了一个副本集,该副本集由以下三个节点组成: 10.192.203.201:27017 PRIMARY 10.192.203.202:27017 SECONDARY 10.192.203.202:10001  ARBITER 二 实验步骤 2.1 模拟环境 use dba; for(var i=0;i<1000000;i++)db.c.

  • OpenStack Ceilometer用MongoDB解决占用磁盘空间过大问题

    OpenStack Ceilometer用MongoDB解决占用磁盘空间过大问题 背景:Ceilometer使用MongoDB作为数据库,不断进行采样,导致数据量膨胀,占用过多的磁盘空间. 知识背景 1.数据库文件类型 1.1. journal 日志文件 跟一些传统数据库不同,MongoDB的日志文件只是用来在系统出现宕机时候恢复尚未来得及同步到硬盘的内存数据.日志文件会存放在一个分开的目录下面.启动时候MongoDB会自动预先创建3个每个为1G的日志文件(初始为空). 1.2. namespa

  • MongoDB释放空闲空间的几种常用方法

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

  • Android顶部状态栏透明化并释放空间的两种实现方法

    由于项目需求,需要将布局顶部放大状态栏的空间,类似这种 在网上搜索找到两种方法: if (Build.VERSION.SDK_INT >= 19){ WindowManager.LayoutParams localLayoutParams = mActivity.getWindow().getAttributes(); localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayo

  • Ubuntu上释放空间的5种简单方法

    前言 大多数人可能在系统磁盘存储不足的情况下执行释放空间这个操作,也可能在 Linux 系统磁盘存储满了的情况下执行这个操作. 它应该被经常执行,来为安装一个新的应用程序和处理其它文件弥补磁盘存储空间.保持可用空间是 Linux 管理员的一个日常任务,以允许磁盘利用率维持在阈值之下. 这里有一些我们可以清理我们系统空间的方法. 当你有 TB 级存储容量时,可能不需要清理你的系统.但是,如果你空间有限,那么释放磁盘空间就变的不可避免. 在这篇文章中,我将向你展示一些最容易的或简单的方法来清理你的

  • MongoDB磁盘IO问题的3种解决方法

    IO概念 在数据库优化和存储规划过程中,总会提到IO的一些重要概念,在这里就详细记录一下,对这个概念的熟悉程度也决定了对数据库与存储优化的理解程度,以下这些概念并非权威文档,权威程度肯定就不能说了. 读/写IO,最为常见说法,读IO,就是发指令,从磁盘读取某段扇区的内容.指令一般是通知磁盘开始扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区个数,同时给出动作是读,还是写.磁盘收到这条指令,就会按照指令的要求,读或者写数据.控制器发出的这种指令+数据,就是一次IO,读或者写. 大/小块IO,

  • 分享MongoDB修改oplog大小的4种方法

    目录 方法一 方法二 方法三 1.关闭mongod 2.修改配置文件 3.启动mongod实例,并备份oplog 4.重建oplog 5.插入前面保存的oplog时间点记录 6.关闭mongod实例 方法四 1.查看oplog大小 2.修改oplog大小 3.验证oplog大小 4.整理碎片,回收空间(可选) 修改oplog有四种方法: 方法一 步骤如下: 停掉所有secondary节点 主节点删除local目录下文件,副本节点删除数据目录下所有文件 修改所有节点的配置文件,如:oplogSiz

  • mysql中如何优化表释放表空间

    目录 mysql优化表释放表空间 mysql空间释放 查询占用空间大小 清理碎片 总结 mysql优化表释放表空间 方法一:optimize table table_name 这是我们经常见到的方法,这里就不在过多介绍. 方法二:alter table table_name engine=engine_name 该方法通常用于切换表的引擎,例如MyISAM转为InnoDB,但是同样适用于释放表空间,只不过切换后的引擎和原来的engine相同罢了. 注意事项 1.这两种方式都适用于我们常用的表,m

  • 关于Linux反空闲设置的两种方法总结

    为了增强Linux系统的安全性,我们需要在用户输入空闲一段时间后自动断开,这个操作可以由设置TMOUT值来实现.或者使用客户端工具,例如securecrt连接linux服务器,有的会出现过一段时间没有任何操作,客户端与服务器就断开了连接.造成这个的原因,主要是因为客户端与服务器之间存在路由器,防火墙以及为了本身的安全性,在超过特定的时间后就会把空闲连接断开.或者是服务器端设置了断开空闲连接.那么解决的方法有两种,一是从服务器着手,一是在客户端工具上下手. 方式一:设置服务器端 1.echo $T

  • JS简单判断字符在另一个字符串中出现次数的2种常用方法

    本文实例讲述了JS简单判断字符在另一个字符串中出现次数的2种常用方法.分享给大家供大家参考,具体如下: 经过搜索验证,提供两个方法. 1. 通过分割获取长度原理 var s = 'www.jb51.net'; var n = (s.split('.')).length-1; alert(n); //弹出2 2. 通过正则实现 function patch(re,s){ re=eval("/"+re+"/ig") return s.match(re).length;

  • Python实现获取磁盘剩余空间的2种方法

    本文实例讲述了Python实现获取磁盘剩余空间的2种方法.分享给大家供大家参考,具体如下: 方法1: import ctypes import os import platform import sys def get_free_space_mb(folder): """ Return folder/drive free space (in bytes) """ if platform.system() == 'Windows': free_by

随机推荐