对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

rewriteCollection(数据库命令)

rewriteCollection

使用相同的分片键将分片集合重写到磁盘。

使用此命令可在添加或删除分片时重新分布数据,或回收磁盘空间。

要停止正在进行的集合重写,请使用 abortRewriteCollection 命令。

8.3版本新增。

此命令可用于以下环境中托管的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

注意

所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令。

该命令具有以下语法:

db.adminCommand( { rewriteCollection: "<database>.<collection>", numInitialChunks: <int>, zones: <zones>} )

该命令接受以下字段:

字段
类型
说明

rewriteCollection

字符串

必需。要重写的数据库和集合的名称。

numInitialChunks

整型

可选.用于对集合重新分片的初始数据段数。默认为 90。

zones

阵列

可选.为分片键指定区域的文档。

在开始重写集合之前,请确保满足以下要求:

  • 您的应用程序可以允许受影响的集合块进行两秒钟的写入。 在写入受阻期间,应用程序的延迟会增加。

    如果您的工作负载无法允许此要求,请考虑改为改进分片键。

  • 您的数据库符合这些资源要求:

    • 确保每个接收分片上的可用存储空间至少是要重写的集合的存储大小加上其总索引大小的两倍,再除以分片的数量:

      ( ( collection_storage_size + index_size ) * 2 ) / shard_count = storage_req

      示例,考虑一个存储大小为 2 TB 数据和 400 GB 索引的集合。要将其分发到四个分片,您需要:

      ( ( 2 TB collection + 0.4 TB index ) * 2 ) / 4 shards = 1.2 TB storage

      要重写此集合,每个分片都需要 1.2TB 的可用存储。

      在MongoDB Atlas上,您可能需要升级到下一个层级存储才能执行重写操作。操作完成后即可降级。

    • 确保 I/O容量低于50 %。

    • 确保 CPU 负载低于80 %。

    重要

    数据库不会强制执行这些要求。未能分配足够的资源可能会导致:

    • 数据库空间不足并关闭

    • 性能下降

    • 操作花费的时间比预期长

    如果应用程序存在流量较少的时间段,请尽可能在该时间段对集合执行此操作。

  • 重新分片之前,无需在新分片键上创建索引。重新分片操作会在索引阶段自动构建所需的索引。

  • 没有正在进行的索引构建。要检查是否正在运行索引构建,请使用 $currentOp:

    db.getSiblingDB("admin").aggregate( [ { $currentOp : { idleConnections: true } }, { $match: { $or: [ { "op": "command", "command.createIndexes": { $exists: true } }, { "op": "none", "msg": /^Index Build/ } ] } }] )

    在结果文档中,如果 inprog 字段值为空数组,则表示没有正在运行的索引构建:

    { inprog: [], ok: 1, '$clusterTime': { ... }, operationTime: <timestamp>}

注意

重写操作是一个写入密集型进程,可以提高oplog的速率。您可能希望:

  • 设置固定的 oplog 大小以防止 oplog 无限增长。

  • 增加 oplog 大小以最大限度地减少一个或多个从节点过时的可能性。

有关更多详细信息,请参阅副本集 Oplog 文档。

rewriteCollection 命令需要对集群或要重写的数据库和集合执行 rewriteCollection 权限操作。

具有以下角色的用户也可以执行此权限操作:

要重写集合,运行以下命令:

db.adminCommand( { rewriteCollection: "sales.orders"} )