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

compact(数据库命令)

compact

对集合中的所有数据和索引进行重写和碎片整理。在 WiredTiger 数据库中,该命令会将不需要的磁盘空间释放给操作系统。

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

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

重要

M0 和 Flex 集群不支持此命令。有关更多信息,请参阅不支持的命令。

该命令具有以下语法:

db.runCommand( { compact: <collection name> })

该命令接受以下字段:

字段
类型
说明

compact

字符串

集合的名称。

force

flag

可选。 如指定,则强制compact 在副本集的主节点上运行。compact 不会阻止正在压缩的数据库上的MongoDB CRUD 操作。

comment

any

可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:

注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。

对于强制进行身份验证的集群,您必须使用对目标集合执行 compact 特权操作的用户身份进行身份验证。dbAdmin 角色提供针对非系统集合运行 compact 所需的特权。

对于系统集合,您必须:

  1. 创建一个自定义角色,该角色授予对系统集合的 compact 操作。

  2. 将该角色授予新用户或现有用户。

  3. 作为该用户进行身份验证,以执行 compact 命令。

例如,以下操作创建一个自定义角色,该角色授予针对指定数据库和集合的 compact 操作:

use admindb.createRole( { role: "myCustomCompactRole", privileges: [ { resource: { "db" : "<database>" , "collection" : "<collection>" }, actions: [ "compact" ] } ], roles: [] })

有关如何配置 resource 文档的详细信息,请参阅有关自管理部署的资源文档。

要将 dbAdmin 或自定义角色添加到现有用户,请使用 db.grantRolesToUser() 或 db.updateUser()。以下操作在 admin 数据库上将自定义 compact 角色授予 myCompactUser:

use admindb.grantRolesToUser("myCompactUser", [ "dbAdmin" | "myCustomCompactRole" ] )

要向新用户添加 dbAdmin 或自定义角色,请在创建用户时对 db.createUser() 方法的 roles 数组指定该角色。

use admindb.createUser( { user: "myCompactUser", pwd: "myCompactUserPassword", roles: [ { role: "dbAdmin", db: "<database>" } | "myCustomCompactRole" ] })

要检查 compact 操作的进度,请监控 mongod 日志文件或从另一个 shell 实例运行 db.currentOp()。

如果在 compact 完成之前重新启动服务器,该操作则会终止,并且在将磁盘空间发布回操作系统的尝试中可能会失败。

compact 命令试图通过向操作系统释放过时块来减少集合中数据和索引的磁盘空间。效果取决于可释放的块数及其在数据文件中的位置。

要查看集合的存储空间如何变化,请在压实之前和之后运行collStats 命令。您可以使用输出指标collStats.freeStorageSize 来查看可供重复使用的存储量。

该操作是迭代式的,并在每次遍历中对数据文件的分段进行操作。对集合调用 compact 会压缩该集合及其关联的索引。

compact 可能需要额外的磁盘空间才能运行。

压实会定期对数据库设置检查点,这可能会导致同步开销。在高流量数据库上,这可能会产生延迟或阻止备份等操作任务。为避免意外中断,请在进行备份之前禁用压实。

注意

如果您的部署使用从节点读和多分片事务,请考虑运行初始同步而不是 compact。

当 compact 运行时,WiredTiger 会临时调整其块管理器策略,以适应压缩工作负载。这种调整可能会减慢检查点操作,并增加成员提交事务所需的时间。事务提交延迟可能会导致显著的读取延迟、复制延迟以及操作排队问题。

您可以在副本集中的集合和索引上使用 compact;但是,请考虑以下内容:

  • 主节点不会将 compact 命令复制到从节点。

  • 尽可能在从节点上运行 compact。如果无法在从节点上运行 compact,请参阅 force 选项。

  • 从 MongoDB 6.1.0开始 (和6.0.2 ):

    • 从节点可以在 compact 运行时进行复制。

    • 允许读取。

要在自管理集群上运行 compact:

1

在其中一个从节点上运行 compact。当 compact 完成后,依次对剩余的每个从节点重复该操作。

2

要降级当前主节点并触发选举,请使用 rs.stepDown() 方法。要指定特定的从节点,请调整节点优先级。

3

降级后,旧的主节点将成为从节点。在旧的主节点上运行 compact。

MongoDB Atlas 不支持 rs.stepDown() 方法或更改节点优先级,因此您无法像在自管理 compact 过程中那样重新分配主节点 (primary node in the replica set)。相反,在 MongoDB Atlas 上,在每个节点上运行 compact。要在当前主节点 (primary node in the replica set) 上运行 compact,请使用 force 选项。要学习在提供服务读取和写入服务的节点上运行 compact 的性能影响,请参阅 多分片事务。

  • 从节点可以在 compact 运行时进行复制。

  • 允许读取。

运行 compact 命令时,副本集将保持 SECONDARY 状态。

有关副本集成员状态的更多信息,请参阅副本集成员状态。

有关副本集维护和可用性,请参阅对自管理副本集节点进行维护。

每个节点独立地将写入应用于其索引。即使节点持有相同数据,副本集的节点之间的索引存储大小也可能会有所不同。主节点直接从客户端操作应用写入。从节点(secondary node from replica set)从 oplog 应用相同的写入,通常以不同的批处理和顺序进行。这些写入模式差异会改变存储引擎打包和压缩索引页的方式。因此,一个节点上的索引在磁盘一上可能比另一个节点上的相同索引大。

要使受影响的索引与其他节点上的相同索引保持一致,请使用以下修复选项之一:

在规划副本集的存储容量时,请考虑节点之间索引大小的差异。

compact 只适用于mongod实例。在分片环境中,在每个分片上分别运行 compact 作为维护操作。

您无法针对 mongos 实例发出 compact。

mongod 在执行 compact 操作后并行重建所有索引。

以下操作将对 movies 集合运行 compact 命令:

db.runCommand( { compact: "movies" } )

运行 compact 会返回类似于以下内容的输出:

{ bytesFreed: 27859, ok: 1 }