Compact Chainweb node databases
Because a healthy blockchain continuously adds new transactions in new blocks that change the state of the database, managing the storage requirements on individual nodes can be challenging.
To address this storage issue, Chainweb provides the compact command-line program.
The compact program enables you to delete historical unused state from the chainweb-node RocksDB database and the Pact SQLite database.
Removing old state that isn't required to validate transactions or reach consensus enables your node to use far less disk space overall while maintaining the semantic integrity of node operations.
Note that, if possible, you should run the compact program on a computer or instance with higher input/output operations per second (IOPS).
For nodes that run as virtual machines or instances on a cloud platform, you can typically configure this setting to optimize performance.
After you compact the state and restart the node to use the compacted database, you can delete the old database to further reduce your storage overhead or save the old database in another location as a backup.
To reduce storage for Chainweb node databases:
-
Open a terminal shell on a computer with access to the
chainweb-nodeyou manage.For example, if you run the node in a Docker container, open a terminal in the container. If you installed
chainweb-nodefrom a release binary or built it from source, open a terminal or secure shell on the computer where the binary is installed. -
Verify that you have access to the
compactcommand-line program by running the following command:compact --helpcompact --helpIf you have access to the
compactprogram, you should see usage information similar to the following:Usage: compact [--chainweb-version ARG] --from ARG --to ARG [--parallel] --log-dir ARG Pact DB Compaction Tool - create a compacted copy of the source database directory Pact DB into the target directory. Available options: --from ARG Directory containing SQLite Pact state and RocksDB block data to compact, expected to be in $DIR/0/{sqlite,rocksDb}. --to ARG Directory where to place the compacted Pact state and block data. It will place them in $DIR/0/{sqlite,rocksDb}, respectively. --parallel Turn on multi-threaded compaction. The threads are per-chain. --log-dir ARG Directory where compaction logs will be placed. -h,--help Show this help textUsage: compact [--chainweb-version ARG] --from ARG --to ARG [--parallel] --log-dir ARG Pact DB Compaction Tool - create a compacted copy of the source database directory Pact DB into the target directory. Available options: --from ARG Directory containing SQLite Pact state and RocksDB block data to compact, expected to be in $DIR/0/{sqlite,rocksDb}. --to ARG Directory where to place the compacted Pact state and block data. It will place them in $DIR/0/{sqlite,rocksDb}, respectively. --parallel Turn on multi-threaded compaction. The threads are per-chain. --log-dir ARG Directory where compaction logs will be placed. -h,--help Show this help text -
Compact your
rocksdbandsqlitedatabases by running thecompactcommand with the following arguments:--fromto specify the path to the database directory you want to compact. You should specify the database root directory that contains the0/sqliteand0/rocksdbsubdirectories. For example, thedata/state/chainweb/dbdirectory is the root directory for thedata/state/chainweb/db/0/sqlitedirectory and thedata/state/chainweb/db/0/rocksdbdirectory.--toto specify the path to the compacted database. The compact program writes the compacted databases to the$DIR/0/sqliteand$DIR/0/rocksdbsubdirectories within the directory you specify.--log-dirto specify the directory where you want thecompactprogram to put the log files it creates, one for each chain. If the directory doesn’t exist, thecompactprogram creates it. These logs can be useful for debugging if something goes wrong.--chainweb-versionto specify the network identifier for the node. This argument is optional if you're compacting a database for themainnet01network. If you're compacting a database for another network—for example, the Kadena test network—you must specify the network identifier. Valid values are "development", "testnet04", and "mainnet01".
For example, if you are using the default location for the database directory and a node connected to the Kadena test network, run a command similar to the following:
compact --from ~/.local/share/chainweb-node/testnet04 --to ~/.local/share/chainweb-node/compact-db --log-dir /tmp/compaction-log-files --chainweb-version testnet04compact --from ~/.local/share/chainweb-node/testnet04 --to ~/.local/share/chainweb-node/compact-db --log-dir /tmp/compaction-log-files --chainweb-version testnet04Note that the location of the Chainweb root database directory—
~/.local/share/chainweb-node/testnet04in this example—depends on the configuration of the node. If you haven't specified a location in the configuration file, the default location is~/.local/share/chainweb-node/{chainweb-network-id}, for example~/.local/share/chainweb-node/testnet04for a node in the Kadena test network.If your node isn't synchronized with the current block height of the network or doesn't have enough history to ensure proper validation, you might see the
compactoperation fail with any error similar to the following:2024-08-09T20:03:38.215Z [Error] [] locateLatestSafeTarget: Not enough history to safely compact. Aborting.2024-08-09T20:03:38.215Z [Error] [] locateLatestSafeTarget: Not enough history to safely compact. Aborting.If you have enough history for compaction to succeed, you should see a message in the terminal similar to the following:
2024-08-13T18:11:30.991Z [Debug] [] Latest Common BlockHeight: 41151622024-08-13T18:11:30.991Z [Debug] [] Earliest Common BlockHeight: 3326042024-08-13T18:11:31.438Z [Debug] [] Compaction target blockheight is: 41141622024-08-13T18:11:31.438Z [Debug] [] targetBlockHeight: 41141622024-08-13T18:11:30.991Z [Debug] [] Latest Common BlockHeight: 41151622024-08-13T18:11:30.991Z [Debug] [] Earliest Common BlockHeight: 3326042024-08-13T18:11:31.438Z [Debug] [] Compaction target blockheight is: 41141622024-08-13T18:11:31.438Z [Debug] [] targetBlockHeight: 4114162All other messages are recorded in the log files in the directory you specified for the
--log-dircommand-line argument. -
Stop your node.
-
Restart your node with the new compacted database directory.
You can specify the new compacted database directory as a command-line option or edit the node configuration file you use to set the new compacted database directory.
For example, you can restart the node with a command similar to the following:
chainweb-node --database-directory=~/.local/share/chainweb-node/compact-dbchainweb-node --database-directory=~/.local/share/chainweb-node/compact-dbIf you're editing the configuration file, update the YAML or JSON file to set the databaseDirectory field to the location of the compacted database. For example:
chainweb: allowReadsInLocal: false backup: api: configuration: {} enabled: false directory: null databaseDirectory: ~/.local/share/chainweb-node/compact-dbchainweb: allowReadsInLocal: false backup: api: configuration: {} enabled: false directory: null databaseDirectory: ~/.local/share/chainweb-node/compact-dbAfter you restart the node, it should run normally with the reduced database size as though nothing has changed. You can delete the old database files or keep them locally or in another location as a backup.
If you encounter errors or warnings, open a new issue for chainweb-node or contact Kadena developers in the infrastructure channel on the Kadena Discord server.