vlambda博客
学习文章列表

MongoDB空间碎片回收

导语

MongoDB删文档或数据的时候不会释放已经占用的空间,当客户端程序重新访问的时候会复用这些空闲的空间。可以通过下列手段对空闲的空间进行碎片整理。

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

  • 1、节点重新同步数据(先从节点依次重新同步,然后主从切换后再同步原主节点)
  • 2、db.copyDatabase()
  • 3、db.repairDatabase()
  • 4、compact

一、节点数据重新同步

3.1 操作步骤

  • 1.当前节点是主节点则先进行降级 rs.stepdown(120),然后再主从切换同步原主节点。
  • 2.移除要同步的从节点。 rs.remove("IP:port")
  • 3.删除secondary节点dbpath下的所有文件。
  • 4.节点重新加入 rs.add("IP:port")自动同步数据。
  • 5.循环以上步骤释放所有节点碎片空间。
  • 6.高版本可以使用 db.runCommand({"resync":1})命令直接重新同步,低的版本可能会出现重新同步异常,需要按照上面步骤处理。

二、db.copyDatabase()

直接拷贝一份新的数据,注意:该命令在4.0中已经被启用。

2.1 使用方法

# 将源库sourceDB。拷贝为DistDB。
db.copyDatabase("sourceDB","DistDB");
  
# 该命令支持远程复制,完整语法为。
db.copyDatabase (<源数据库>, <目标数据库>, <源IP:port>,<源数据库连接的账户>,<密码>,<mechanism>)

以上:命令必须在目标数据库服务器上执行。若源数据库与目标数据库存在于一个MongoDB服务器,<源mongodb的IP:port>, <源数据库连接需要的账户>,<密码>都可省略。 是身份验证类型,可选的。

2.2 注意点

  • 1.不会堵塞主库和目标库读写,因此可能出现拷贝数据不一致的情况。
  • 2. 复制索引数据会锁定数据库
  • 3.不能用于分片数据库。
  • 4.要有 足够的剩余空间,2倍左右的磁盘空间。
  • 6.在4.0版中更改:db.copyDatabase() 仅支持SCRAM进行身份验证 fromhost, 选项。
  • 7.某些不同版本的MongoDB间不支持此种复制方法,详见链接:https://docs.mongodb.com/manual/reference/method/db.copyDatabase/

三、db.repairDatabase()

官网该命令的定义:通过丢无效或损坏的数据老重建数据库和索引。

3.1 使用方法

use database;
db.repairDatabase();

3.2 注意点

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

四、compat

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

4.1 使用方法

use database;
db.runCommand({ compact : 'Collection-name' });

4.2 注意事项

  • 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时会进行压缩。