compact
Definition
compactRewrites and defragments all data and indexes in a collection. On WiredTiger databases, this command releases unneeded disk space to the operating system.
Syntax
The command has the following syntax:
db.runCommand( { compact: <collection name> } )
Command Fields
The command takes the following fields:
Field | Type | Description |
|---|---|---|
compact | string | The name of the collection. |
force | flag | Changed in version 4.4. Optional. If specified, forces
|
comment | any | Optional. A user-provided comment to attach to this command. Once set, this comment appears alongside records of this command in the following locations:
A comment can be any valid BSON type (string, integer, object, array, etc). New in version 4.4. |
Warning
Always have an up-to-date backup before performing server
maintenance such as the compact operation.
compact Required Privileges
For clusters enforcing authentication,
you must authenticate as a user with the compact privilege
action on the target collection. The dbAdmin role provides
the required privileges for running compact against
non-system collections.
For system collections, you must:
Create a custom role that grants the
compactaction on the system collection.Grant that role to a new or existing user.
Authenticate as that user to perform the
compactcommand.
For example, the following operations create a custom role that grants
the compact action against the specified database and
collection:
use admin db.createRole( { role: "myCustomCompactRole", privileges: [ { resource: { "db" : "<database>" , "collection" : "<collection>" }, actions: [ "compact" ] } ], roles: [] } )
For more information on configuring the resource document, see
Resource Document.
To add the dbAdmin or the custom role to an existing
user, use db.grantRolesToUser() or db.updateUser().
The following operation grants the custom compact role to the
myCompactUser on the admin database:
use admin db.grantRolesToUser("myCompactUser", [ "dbAdmin" | "myCustomCompactRole" ] )
To add the dbAdmin or the custom role to a new user,
specify the role to the roles array of the
db.createUser() method when creating the user.
use admin db.createUser( { user: "myCompactUser", pwd: "myCompactUserPassword", roles: [ { role: "dbAdmin", db: "<database>" } | "myCustomCompactRole" ] } )
Behavior
Blocking
Blocking behavior is version specific.
Version | Blocking Behavior |
4.4 |
|
Post 4.4.17, 5.0.12, 6.0.2, 6.1.0 |
|
To run compact in a replica set, see
Replica Sets for additional considerations.
Monitoring Progress
To check the compact operation's progress, monitor the
mongod log file or run db.currentOp()
from another shell instance.
Operation Termination
If you terminate the operation with the db.killOp() method or restart the server before the
compact operation has finished, be aware of the following:
If you have journaling enabled, the data remains valid and usable, regardless of the state of the
compactoperation. You may have to manually rebuild the indexes.If you do not have journaling enabled and the
mongodorcompactterminates during the operation, it is impossible to guarantee that the data is in a valid state.In either case, much of the existing free space in the collection may become un-reusable. In this scenario, you should rerun the compaction to completion to restore the use of this free space.
Disk Space
To see how the storage space changes for the collection, run the
collStats command before and after compaction.
On WiredTiger, compact attempts
to reduce the required storage space for data and indexes in a
collection, releasing unneeded disk space to the operating system. The
effectiveness of this operation is workload dependent and no disk space
may be recovered. This command is useful if you have removed a large
amount of data from the collection, and do not plan to replace it.
compact may require additional disk space to run on
WiredTiger databases.
Replica Sets
You can use compact on collections and indexes that are stored in a
replica set, however there are some important considerations:
The primary node does not replicate the
compactcommand to the secondaries.You should run
compacton secondary nodes whenever possible. If you cannot runcompacton secondaries, see the force option.Starting in MongoDB 6.1.0 (and 6.0.2, 5.0.12, and 4.4.17):
A secondary node can replicate while
compactis running.Reads are permitted.
To run compact on a cluster
Reassign the primary node.
To step down the current primary and trigger an election, use the
rs.stepDown() method. To nominate a particular secondary
node, adjust the member priority.
Version Specific Considerations for Secondary Nodes
Blocking behavior on secondary nodes is version specific.
Version | Blocking Behavior |
4.4 |
|
Post 4.4.17, 5.0.12, 6.0.2, 6.1.0 |
|
Replication status while the compact command is running depends on
your specific MongoDB version:
In MongoDB versions
4.4.9and later, the replica set remains in aSECONDARYstatus.In MongoDB versions earlier than
4.4.9,compactforces the replica set into theRECOVERINGstatus.
For more information about replica set member states, see See Replica Set Member States.
For replica set maintenance and availability, see Perform Maintenance on Replica Set Members.
Sharded Clusters
compact only applies to mongod instances. In a
sharded environment, run compact on each shard separately
as a maintenance operation.
You cannot issue compact against a mongos instance.
Capped Collections
On WiredTiger, the compact
command will attempt to compact the collection.
Index Building
mongod rebuilds all indexes in parallel following the
compact operation.
Example
The following operation runs the compact command on the
movies collection:
db.runCommand( { compact: "movies" } )
Running compact returns output similar to the following:
{ bytesFreed: 27859, ok: 1 }