阿里云数据库 MongoDB 版整理物理空间碎片以提升磁盘利用率

MongoDB数据库在长期频繁地删除/写入数据或批量删除了大量数据,将产生很多物理空间碎片。这些碎片将占用磁盘空间,降低磁盘利用率。您可以对集合中的所有数据和索引进行重写和碎片整理,释放未使用的空间,提升磁盘利用率和查询性能。

前提条件

实例的存储引擎为WiredTiger。

注意事项

  • 执行该操作前,建议对数据库进行备份,详情请参见手动备份MongoDB数据。
  • 执行该操作会导致集合所属的数据库被锁定,且该数据库的读写操作将被阻塞,请在业务低峰期操作。


    说明 执行物理空间回收命令(compact)所需的时间与集合数据量、系统负载等因素有关。

背景信息

空间回收原理空间回收原理

通常情况下,使用db.collection.remove({}, {multi: true})命令删除文档,文档将从btree中删除,但是文档占用的物理空间不会被回收。如果执行remove命令删除了大量的文档,且后续的数据写入操作很少,这将降低磁盘利用率,此时可执行compact命令回收空闲的物理空间。


说明

  • 新写入的数据将会使用未被回收的物理空间,所以在数据持续写入的场景中,不需要频繁执行compact命令整理物理空间碎片。
  • 如您使用db.collection.drop()命令删除集合,那么集合的物理文件会被删除,且物理空间会被回收。

预估回收的物理空间

  1. 通过mongo shell连接MongoDB实例,详情请参见:
    • Mongo Shell连接单节点实例
    • Mongo Shell连接副本集实例
    • Mongo Shell连接分片集群实例
  2. 切换至集合所在的数据库。
    use <database_name>


    说明 <database_name>:数据库名。

  3. 执行下列命令查询。
    db.<collection_name>.stats().wiredTiger["block-manager"]["file bytes available for reuse"]


    说明 <collection_name>:集合名。

    查询示例:

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

    执行结果示例:

    207806464

整理单节点实例/副本集实例的碎片

  1. 通过mongo shell连接MongoDB实例的Primary节点,详情请参见mongoshell连接实例。
  2. 切换至集合所在的数据库。
    use <database_name>


    说明 <database_name>:数据库名。

  3. 执行db.stats()命令查看碎片整理前数据库占用的磁盘空间。
  4. 执行以下命令,对某个集合进行碎片整理。
    db.runCommand({compact:"<collection_name>",force:true})


    说明

    • <collection_name>:集合名。
    • force为可选项,如您需要在副本集实例的Primary节点执行该命令,需要设置force的值为true
  5. 等待执行,返回{ "ok" : 1 }代表执行完成。


    说明 compact操作不会传递给Secondary节点,当实例为副本集实例时,请重复上述步骤通过mongo shell连接至Secondary节点,执行碎片整理命令。

    碎片整理完毕后,可通过db.stats()命令查看碎片整理后数据库占用的磁盘空间。本案例碎片整理前后的对比如下图所示。
    compact前后对比compact前后对比

整理分片集群实例的碎片

  1. 通过mongo shell连接分片集群实例中的任一mongos节点,详情请参见mongo shell连接分片集群实例。
  2. 执行db.stats()命令查看碎片整理前数据库占用的磁盘空间。
  3. 执行以下命令,对Shard节点中的Primary节点进行集合的碎片整理。
    db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>",force:true}})


    说明

    • <Shard ID>:Shard节点ID。
    • <collection_name>:集合名。
  4. 执行以下命令,对Shard节点中的Secondary节点进行集合的碎片整理。
    db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"},queryOptions: {$readPreference: {mode: 'secondary'}}})


    说明

    • <Shard ID>:Shard节点ID。
    • <collection_name>:集合名。

    碎片整理完毕后,可通过db.runCommand({dbstats:1}) 命令查看碎片整理后数据库占用的磁盘空间。

相关问题

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

原创文章,作者:网友投稿,如若转载,请注明出处:https://www.cloudads.cn/archives/33806.html

发表评论

登录后才能评论