云数据库MongoDB实例在使用过程中,删除数据并不会回收磁盘空间,这些未被回收的磁盘空间被称为磁盘碎片。频繁删除数据或删除大量数据后,会产生很多磁盘碎片。本文介绍如何回收磁盘碎片以提升磁盘利用率。
前提条件
实例的存储引擎为WiredTiger。
背景信息
执行
db.runCommand({collStats: <collection_name>})
命令访问节点时,返回结果有两个关键字:size
和storageSize
。其中,size
表示集合的逻辑存储大小,storageSize
表示集合的物理存储大小。在执行remove
命令删除文档后,size
的值会减少,但是,storageSize
的值不一定会减少。通过比较size
和storageSize
的大小,可以判断是否产生磁盘碎片。
说明
- 云数据库MongoDB 4.4及以上版本,还可以通过返回结果的
freeStorageSize
关键字查看磁盘碎片中空闲并可以被回收的磁盘空间。 - 关于
size
、storageSize
和freeStorageSize
关键字的更多信息,请参见collStats-Output。
compact
是云数据库MongoDB的压缩命令,执行compact
命令可以回收删除数据后产生的磁盘碎片,实现压缩磁盘空间的目的,从而提升磁盘利用率。关于compact
命令的更多信息,请参见compact。
当磁盘碎片率不高时,执行compact
命令会因为云数据库MongoDB实例的WiredTiger存储引擎限制,达不到预期效果,因此,不建议频繁执行compact
命令。
当集合的数据量比较小时,您可以将数据拷贝到一个新集合,再执行db.collection.drop()
命令删除旧集合,从而提升磁盘利用率。执行db.collection.drop()
命令删除集合时,集合中的文件会被全部删除,并且磁盘空间会被回收。
注意事项
- 回收磁盘碎片前,建议对数据库进行备份,如何备份,请参见手动备份MongoDB数据。
- 回收磁盘碎片会导致集合所属的数据库被锁定,且该数据库的读写操作将被阻塞,建议您在业务低峰期操作。
说明 执行
compact
命令回收磁盘碎片所需的时间与集合数据量、系统负载等因素有关。
预估回收的磁盘碎片空间
回收单节点或副本集实例的磁盘碎片
- 单节点实例只有一个StandAlone节点,您只需要连接主节点(Primary节点),执行
compact
命令回收主节点(Primary节点)的磁盘碎片。 - 副本集实例具有多个节点,您需要分别连接主节点(Primary节点)和从节点(Secondary节点),在不同节点上执行
compact
命令回收相应节点的磁盘碎片,执行的回收命令相同。说明 如果副本集实例具有只读节点(Readonly节点),您还需要回收只读节点(Readonly节点)的磁盘碎片,执行的回收命令与回收主从节点磁盘碎片的命令相同。
回收分片集群实例的磁盘碎片
分片集群实例只需要回收Shard组件中对应节点的磁盘碎片。Mongos组件和ConfigServer组件均不存储用户数据,并且增加和更新操作偏多,删除操作偏少,不需要回收磁盘碎片。
说明 分片集群实例的只读节点不支持
compact
命令,所以无法回收只读节点(ReadOnly节点)的磁盘碎片。