- 文档首页
文档数据库 MongoDB 版
最佳实践
通过 COMPACT 命令回收 MongoDB 实例磁盘碎片
最佳实践
通过 COMPACT 命令回收 MongoDB 实例磁盘碎片
通过 COMPACT 命令回收 MongoDB 实例磁盘碎片
本文介绍如何通过 compact 命令回收 MongoDB 实例的磁盘碎片,减少磁盘使用压力,提高利用率。
背景信息
文档数据库 MongoDB 版实例在删除数据时,不会直接回收被删除数据的磁盘空间(这些空间会被标记为空闲),后续新写入的数据不会占用新的磁盘空间,而是重用之前空闲的磁盘空间,那些未被使用的空闲存储空间则被称作磁盘碎片。随着删除的操作增多,碎片也会越来越多,磁盘碎片越多表明磁盘利用率越低。
compact 命令可用于重写和整理 MongoDB 集合中所有的数据和索引,通过回收数据删除后所产生的磁盘碎片来提升磁盘利用率。关于 compact 命令的更多信息,请参见 compact。 前提条件
文档数据库 MongoDB 版支持副本集和分片集群两种架构的实例,实例类型不同,执行 compact 命令回收磁盘空间时的前提条件不同。
已分别获取实例的主节点(Primary node)、从节点(Secondary node)、隐藏节点(Hidden node)的单节点连接地址。
您可以登录 MongoDB 控制台后,在目标副本集实例连接管理页签下的单节点地址表格中查看各节点的连接地址。具体操作步骤,请参见查看连接地址。
- 已为目标 shard 分片申请私网连接地址。具体操作步骤,请参见申请私网地址。
说明
文档数据库 MongoDB 版分片集群实例只需回收 Shard 组件中对应节点的磁盘碎片。Mongos 和 ConfigServer 组件均不存储业务数据,并且增加和更新操作偏多,删除操作偏少,一般不需要回收磁盘碎片。关于分片集群实例各组件的更多信息,请参见分片集群。 - 已分别获取 shard 分片中主节点、从节点和隐藏节点的单节点连接地址。
- 您可以登录 MongoDB 控制台后,在目标分片集群实例连接管理页签下的连接Shard 区域,单击目标 shard 右侧的
图标,在展开的表格中查看各节点的连接地址。具体操作步骤,请参见查看连接地址。
-
注意事项
- 建议在回收磁盘碎片前,先对数据库数据进行备份。数据备份的具体方法,请参见手动备份。
- 集合数据量、系统负载等因素会影响回收磁盘碎片的执行时间。
- 针对 MongoDB 4.4 及之前版本的实例,在非隐藏节点(Hidden node)上执行 compact 命令会导致集合所属的数据库被锁定,且会阻塞数据库的读写操作。建议您在业务低峰期,严格按照本文操作顺序进行磁盘碎片回收操作,减少对业务的影响。关于受阻塞命令的更多详情,请参见 Blocking。若您在回收磁盘空间操作过程中遇到问题,请提交工单联系技术支持。
- 执行 compact 命令操作时会产生复制延迟,若延迟时间超出 oplog 窗口期,极有可能导致主从节点复制失败,甚至引发节点异常。强烈建议在执行 compact 命令期间,密切关注实例的主备延时指标,以及 oplog 保留窗不足的事件告警。若复制延迟过大,请及时终止 compact 命令操作。更多关于oplog 参数的详情,请参见 oplog 相关参数设置指南。
- 如需终止当前 compact 命令操作,您可以新建一个连接后,通过 db.killOp(opid) 命令来终止正在运行中的 compact 操作。关于 db.killOp() 命令的更多详情,请参见 db.killOp() 。
预估可回收的磁盘碎片空间
说明
对于 MongoDB 副本集实例,为降低业务影响,建议您连接副本集实例的从节点(Secondary node)操作。
- 执行 use <数据库名称> 命令进入目标数据库。
说明
您可以通过 show dbs 命令查询当前 MongoDB 实例中的已有的数据库。
- 通过 collStats 命令查看目标集合的存储空间状况。
说明
您可以通过 show tables 命令查询现有当前数据库中已有的集合。
- collStats.freeStorageSize:表示磁盘碎片中空闲并可以被回收的磁盘空间。您也可以查看返回结果中 block-manager 结构下的 file bytes available for reuse 字段获取可回收的磁盘空间信息。
说明
- 通过 delete 命令删除文档后,size 的值会减少,但 storageSize 的值不一定会减少。您可以观察 freeStorageSize 在 storageSize 中的占比,占比率较高时,代表磁盘碎片率较高。
- 文档数据库 MongoDB 4.4 及以上版本才支持查看 freeStorageSize 字段。更多关于 collStats 命令的信息,请参见 collStats。
回收实例磁盘碎片
回收副本集实例的磁盘碎片
回收分片集群实例的磁盘碎片
- 在安装了 Mongo shell 的本地服务器或 ECS 中,在如下命令的对应位置输入副本集实例的数据库账号、密码,以及隐藏节点(Hidden node)的单节点连接地址来连接隐藏节点。
- 执行 rs.isMaster() 命令确认当前连接的节点是否为隐藏节点。
说明
如下示例中仅展示了部分字段。返回结果中 hidden 字段值为 true,即表明当前连接的是隐藏节点。
- 本文以 test_collect 为例,命令示例如下。
- 若返回结果中出现 "ok" : 1 ,即表示 compact 命令执行成功。
- 在安装了 Mongo shell 的本地服务器或 ECS 中,在如下命令的对应位置输入副本集实例的数据库账号、密码,以及从节点(Secondary node)的单节点连接地址来连接从节点。
- 执行 rs.isMaster() 命令确认当前连接的节点是否为从节点。
说明
如下示例中仅展示了部分字段。返回结果中 secondary 字段值为 true,即表明当前连接的是从节点。
说明
在从节点中执行 compact 命令的方法和在隐藏节点上的一样。具体的命令详情和示例,请参见上文中的步骤一:回收隐藏节点上的磁盘碎片。
手动将已完成磁盘碎片回收的从节点切换为主节点,详细操作步骤,请参见切换主节点。 说明
- 手动切换主节点过程(一般需要 30~60 秒)中,实例可能会出现 1~2 次连接闪断,请谨慎操作。建议在业务低峰期执行切换操作,并确保应用具备自动重连机制。
- 手动切换主节点仅改变节点的角色,不会改变节点所在的可用区和节点 ID。
主节点切换成功后,参考回收从节点上磁盘碎片的相关步骤,连接到切换后的新从节点并完成磁盘碎片回收。具体操作步骤,请参见上文中的步骤二:回收从节点上的磁盘碎片。
说明
MongoDB 分片集群实例只需要回收 Shard 组件中对应节点的磁盘碎片。Mongos 组件和 ConfigServer 组件均不存储业务数据,且这两个组件记录的增加和更新操作偏多,删除操作偏少,因此不需要回收磁盘碎片。
- 在安装了 Mongo shell 的本地服务器或 ECS 中,在如下命令的对应位置输入分片集群实例的数据库账号、密码,以及目标 shard 中隐藏节点(Hidden node)的单节点连接地址来连接隐藏节点。
- 执行 rs.isMaster() 命令确认当前连接的节点是否为隐藏节点。
说明
如下示例中仅展示了部分字段。返回结果中 hidden 字段值为 true,即表明当前连接的是 隐藏节点。
- 本文以 test_collect 为例,命令示例如下。
- 若返回结果中出现 "ok" : 1 ,即表示 compact 命令执行成功。
- 在安装了 Mongo shell 的本地服务器或 ECS 中,在如下命令的对应位置输入分片集群实例的数据库账号、密码,以及目标 shard 中从节点(Secondary node)的单节点连接地址来连接从节点。
- 执行 rs.isMaster() 命令确认当前连接的节点是否为从节点。
说明
如下示例中仅展示了部分字段。返回结果中 secondary 字段值为 true,即表明当前连接的是从节点。
说明
在从节点中执行 compact 命令的方法和在隐藏节点上的一样。具体的命令详情和示例,请参见上文中的步骤一:回收 shard 上隐藏节点的磁盘碎片。
手动将已完成磁盘碎片回收的从节点切换为主节点,详细操作步骤,请参见切换主节点。 注意
- 手动切换主节点过程(一般需要 30~60 秒)中,实例可能会出现 1~2 次连接闪断,请谨慎操作。建议在业务低峰期执行切换操作,并确保应用具备自动重连机制。
- 手动切换主节点仅改变节点的角色,不会改变节点所在的可用区和节点 ID。
步骤四:回收 shard 上新从节点上的磁盘碎片
主节点切换成功后,参考回收从节点上的磁盘碎片相关步骤,连接到切换后的新从节点并完成磁盘碎片回收。具体操作步骤,请参见上文中的步骤二:回收 shard 上从节点的磁盘碎片。
最近更新时间:2026.01.29 22:05:53