Operations: Server: How to Compact a Database

  • Use the CompactDatabaseOperation to compact a database.
  • You can choose what should be compacted: documents and/or listed indexes.

The compacting operation is executed asynchronously, and during this operation the database will be offline.

Syntax

public CompactDatabaseOperation(CompactSettings compactSettings)

public class CompactSettings
{
    public string DatabaseName { get; set; }

    public bool Documents { get; set; }

    public string[] Indexes { get; set; }
}
Parameters
DatabaseName string Name of a database to compact
Documents bool Indicates if documents should be compacted
Indexes string[] List of index names to compact

Example I

CompactSettings settings = new CompactSettings
{
    DatabaseName = "Northwind",
    Documents = true,
    Indexes = new[] { "Orders/Totals", "Orders/ByCompany" }
};
Operation operation = store.Maintenance.Server.Send(new CompactDatabaseOperation(settings));
operation.WaitForCompletion();

Example II

// get all index names
string[] indexNames = store.Maintenance.Send(new GetIndexNamesOperation(0, int.MaxValue));

CompactSettings settings = new CompactSettings
{
    DatabaseName = "Northwind",
    Documents = true,
    Indexes = indexNames
};
// compact entire database: documents + all indexes
Operation operation = store.Maintenance.Server.Send(new CompactDatabaseOperation(settings));
operation.WaitForCompletion();

Example III

  • CompactDatabaseOperation automatically runs on the store's database.
    If we try to compact a different database, the process will succeed only if the database resides on the cluster's first online node.
    Trying to compact a non-default database on a different node will fail with an error such as -
    "500 Internal Server Error : System.InvalidOperationException , Cannot compact database 'name' on node A, because it doesn't reside on this node."

  • To solve this, we can explicitly identify the database we want to compact by providing its name to CompactDatabaseOperation as in the following example.

    using (var store = new DocumentStore
    {
        Urls = new[] { "http://localhost:8080" },
        Database = "sampleDB" // the store's database
    }.Initialize())
    {
        store.GetRequestExecutor().GetPreferredNode().Wait();
    
        const string DBToCompact = "NonDefaultDB"; // the database we want to compact
        string[] indexNames = store.Maintenance.Send(new GetIndexNamesOperation(0, int.MaxValue));
    
        var compactOperation = new CompactDatabaseOperation(new Raven.Client.ServerWide.CompactSettings
        {
            DatabaseName = DBToCompact,
            Documents = true,
            Indexes = indexNames
        });
    
        // Get request executor for our DB
        var reqEx = store.GetRequestExecutor(DBToCompact);
    
        using (reqEx.ContextPool.AllocateOperationContext(out var context))
        {
            var compactCommand = compactOperation.GetCommand(store.Conventions, context);
            reqEx.Execute(compactCommand, context);
        }
    }