文档

回收磁盘碎片以提升磁盘利用率

在删除云数据库MongoDB实例的数据后,这些被删除数据使用的存储空间会被标记为空闲,随后写入的新数据可能会被直接存储到这部分空闲的存储空间中,也可能会先扩展文件的存储空间再存储到文件末尾。上述情况将导致一部分空闲的存储空间不会被使用,这些未被使用的空闲存储空间被称之为磁盘碎片,磁盘碎片越多,磁盘利用率就越低。

您也可以通过空间分析功能查询云数据库 MongoDB 版实例的空间概况、空间变化趋势、异常列表、数据空间以及回收空间碎片。具体操作,请参见空间分析

前提条件

实例的存储引擎为WiredTiger。

背景信息

执行db.runCommand({collStats: <collection_name>}) 命令访问节点时,返回结果有两个关键字:sizestorageSize。其中,size表示集合的逻辑存储大小,storageSize表示集合的物理存储大小。在执行remove命令删除文档后,size的值会减少,但是,storageSize的值不一定会减少。当storageSize大于size时,表示已产生磁盘碎片。

说明
  • 云数据库MongoDB 4.4及以上版本,还可以通过返回结果的freeStorageSize关键字查看磁盘碎片中空闲并可以被回收的磁盘空间。

  • 关于sizestorageSizefreeStorageSize关键字的更多信息,请参见collStats-Output

compact是云数据库MongoDB的压缩命令,执行compact命令可以回收删除数据后产生的磁盘碎片,实现压缩磁盘空间的目的,从而提升磁盘利用率。关于compact命令的更多信息,请参见compact

注意事项

  • 回收磁盘碎片前,建议对数据库数据进行备份,备份方法,请参见手动备份MongoDB数据

  • MongoDB 4.4之前的版本执行compact命令会导致集合所属的数据库被锁定,且该数据库的读写操作将被阻塞,建议您在业务低峰期操作。受阻塞的具体介绍,请参见MongoDB官网文档

    说明

    执行compact命令回收磁盘碎片所需的时间与集合数据量、系统负载等因素有关。

  • MongoDB 3.4、MongoDB 4.2的4.0.22及以前内核版本和MongoDB 4.4的5.0.6及以前的内核版本,正在执行compact命令的节点会进入RECOVERING状态,如果持续时间过长,该节点会被实例探活组件认定为节点不健康从而触发相应的重搭操作。上述版本以后的MongoDB实例,执行compact命令的节点则会维持在SECONDARY状态,不会触发重搭操作。详细信息,请参见MongoDB官方文档。关于MongoDB版本的更多信息,请参见MongoDB小版本说明

  • 以下场景可能会导致compact命令执行无效,更多介绍请参见开源代码

    • 物理集合大小小于1 MB。

    • 文件前80%的存储空间中,空闲存储空间小于20%;文件前90%的存储空间中,空闲存储空间小于10%。

  • 执行compact命令时,可能会出现释放的存储空间小于空闲的存储空间的情况。如果出现上述情况,您可以重复执行compact命令来释放磁盘碎片,但不建议您频繁执行compact命令。

  • compact命令可以在磁盘空间满导致实例锁定的情况下执行。

预估回收的磁盘碎片空间

  1. 通过MongoDB Shell连接云数据库MongoDB实例。不同类型实例的连接方法如下:

  2. 将数据库切换至集合所在的数据库。

    语法:

    use <database_name>

    参数说明:<database_name>为集合所在的数据库名称。

    说明

    您可以通过show dbs命令查询现有的数据库。

    示例:

    切换至test_database数据库。

    use test_database
  3. 查看集合需回收的磁盘碎片空间。

    语法:

    db.<collection_name>.stats().wiredTiger["block-manager"]["file bytes available for reuse"]

    参数说明:<collection_name>为集合名称。

    说明

    您可以通过show tables命令查询现有的集合。

    示例:

    db.test_database_collection.stats().wiredTiger["block-manager"]["file bytes available for reuse"]

    返回结果如下:

    207806464

    该返回结果表示预估回收的磁盘碎片空间为207806464 Byte。

回收单节点或副本集实例的磁盘碎片

  • 单节点实例只有一个StandAlone节点,您只需要连接主节点(Primary节点),执行compact命令回收主节点(Primary节点)的磁盘碎片。

  • 副本集实例具有多个节点,您需要分别连接主节点(Primary节点)和从节点(Secondary节点),在不同节点上执行compact命令回收相应节点的磁盘碎片,执行的回收命令相同。

    说明

    如果副本集实例具有只读节点(Readonly节点),您还需要回收只读节点(Readonly节点)的磁盘碎片,执行的回收命令与回收主从节点磁盘碎片的命令相同。

  1. 通过Mongo Shell连接单节点或副本集实例。不同类型实例的连接方法如下:

  2. 将数据库切换至集合所在的数据库。

    语法:

    use <database_name>

    参数说明:<database_name>为集合所在的数据库名称。

    说明

    您可以通过show dbs命令查询现有的数据库。

    示例:

    切换至replica_database数据库。

    use replica_database
  3. 查看回收磁盘碎片前数据库占用的磁盘空间。

    db.stats()
    说明

    该命令可以直接复制执行,无需修改。

  4. 回收集合的磁盘碎片。

    语法:

    db.runCommand({compact:"<collection_name>",force:true})

    参数说明:

    • <collection_name>:集合名称。

      说明

      您可以通过show tables命令查询现有的集合。

    • force:可选项,取值固定为true

      如果您在4.2及以下版本的云数据库MongoDB实例主节点(Primary节点)上执行该命令,该参数为必填项。

    示例:

    db.runCommand({compact:"sharded_collection"})

    执行成功的返回结果如下:

    { "ok" : 1 }
  5. 查看回收磁盘碎片后数据库占用的磁盘空间。

    db.stats()
    说明

    该命令可以直接复制执行,无需修改。

回收分片集群实例的磁盘碎片

分片集群实例只需要回收Shard组件中对应节点的磁盘碎片。Mongos组件和ConfigServer组件均不存储用户数据,并且增加和更新操作偏多,删除操作偏少,不需要回收磁盘碎片。

说明

分片集群实例的只读节点不支持compact命令,所以无法回收只读节点(ReadOnly节点)的磁盘碎片。

  1. 通过Mongo Shell连接分片集群实例,如何连接,请参见通过Mongo Shell连接MongoDB分片集群实例

  2. 将数据库切换至集合所在的数据库。

    语法:

    use <database_name>

    参数说明:<database_name>为集合所在的数据库名称。

    说明

    您可以通过show dbs命令查询现有的数据库。

    示例:

    切换至sharded_database数据库。

    use sharded_database
  3. 查看回收磁盘碎片前数据库占用的磁盘空间。

    db.stats()
    说明

    该命令可以直接复制执行,无需修改。

  4. 回收集合的磁盘碎片。

    您需要分别回收Shard组件中主节点(Primary节点)和从节点(Secondary节点)的磁盘碎片。

    • 回收Shard组件中主节点(Primary节点)的磁盘碎片。

      语法:

      db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>",force:true}})

      参数说明:

      • <Shard ID>:Shard组件的ID。

        说明

        您可以登录MongoDB管理控制台,在目标实例基本信息页面的Shard列表区域查看Shard组件的ID。

      • <collection_name>:集合名称。

        说明

        您可以通过show tables命令查询现有的集合。

      • force:可选项,取值固定为true

        如果您的分片集群实例版本为4.2及以下版本,该参数为必填项。

      示例:

      db.runCommand({runCommandOnShard:"shard01","command":{compact:"sharded_collection",force:true}})
    • 回收Shard组件中从节点(Secondary节点)的磁盘碎片。

      语法:

      db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"},$queryOptions: {$readPreference: {mode: 'secondary'}}})

      参数说明:

      • <Shard ID>:Shard组件的ID。

        说明

        您可以登录MongoDB管理控制台,在目标实例基本信息页面的Shard列表区域查看Shard组件的ID。

      • <collection_name>:集合名称。

        说明

        您可以通过show tables命令查询现有的集合。

      示例:

      db.runCommand({runCommandOnShard:"shard01","command":{compact:"sharded_collection"},$queryOptions: {$readPreference: {mode: 'secondary'}}})
  5. 查看回收磁盘碎片后数据库占用的磁盘空间。

    db.stats()
    说明

    该命令可以直接复制执行,无需修改。

相关问题

解决因磁盘空间耗尽导致的锁定或无法写入问题

  • 本页导读 (1)
文档反馈