You need to enable JavaScript to run this app.
文档中心
文档数据库 MongoDB 版

文档数据库 MongoDB 版

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