DatabaseChangeLog Table Management
Relevant source files
The following files were used as context for generating this wiki page:
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/CreateDatabaseChangeLogTableClickHouse.java
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/CreateDatabaseChangeLogLockTableClickHouse.java
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/InitializeDatabaseChangeLogLockClickHouse.java
- src/main/java/liquibase/ext/clickhouse/database/ClickHouseDatabase.java
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/SqlGeneratorUtil.java
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/UpdateChangeSetChecksumClickHouse.java
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/TagDatabaseGeneratorClickhouse.java
- src/main/java/liquibase/ext/clickhouse/params/ParamsLoader.java
The management of the DatabaseChangeLog and DatabaseChangeLogLock tables in the Liquibase ClickHouse extension ensures that database schema migrations are tracked and synchronized correctly across ClickHouse instances. Because ClickHouse handles transactions and mutations differently than standard relational databases (e.g., lack of DDL in transactions), this extension provides specialized SQL generators to handle table creation, locking, and status updates specifically for the ClickHouse engine.
Sources: src/main/java/liquibase/ext/clickhouse/database/ClickHouseDatabase.java:85, src/main/java/liquibase/ext/clickhouse/sqlgenerator/CreateDatabaseChangeLogTableClickHouse.java:45-50
Table Creation and Schema
The extension overrides the default Liquibase behavior to create tracking tables compatible with ClickHouse's storage engines. It supports both standalone MergeTree and ReplicatedMergeTree for cluster environments.
DatabaseChangeLog Table Structure
The DATABASECHANGELOG table tracks which changesets have been applied to the database.
| Field | Type | Description |
|---|---|---|
| ID | String | Unique identifier for the changeset |
| AUTHOR | String | Author of the changeset |
| FILENAME | String | Path to the changelog file |
| DATEEXECUTED | DateTime64 | Execution timestamp |
| ORDEREXECUTED | UInt64 | Order of execution |
| EXECTYPE | String | Type of execution (e.g., EXECUTED) |
| MD5SUM | Nullable(String) | Checksum of the changeset |
| DESCRIPTION | Nullable(String) | Description of the change |
| COMMENTS | Nullable(String) | User comments |
| TAG | Nullable(String) | Tag assigned to the database state |
| LIQUIBASE | Nullable(String) | Liquibase version used |
| CONTEXTS | Nullable(String) | Contexts applied during execution |
| LABELS | Nullable(String) | Labels applied during execution |
| DEPLOYMENT_ID | Nullable(String) | ID of the deployment |
DatabaseChangeLogLock Table Structure
The DATABASECHANGELOGLOCK table manages concurrent access during migrations.
| Field | Type | Description |
|---|---|---|
| ID | Int64 | Identifier (typically 1) |
| LOCKED | UInt8 | Boolean flag (0 or 1) |
| LOCKGRANTED | Nullable(DateTime64) | Timestamp when lock was acquired |
| LOCKEDBY | Nullable(String) | Host/Process description holding the lock |
Architectural Components
The following diagram illustrates how the extension selects the appropriate SQL generation strategy based on the database type and cluster configuration.
The system uses SqlGeneratorUtil to append ON CLUSTER clauses and determine the appropriate ENGINE based on whether liquibaseClickhouse.conf provides cluster parameters.
Sources: src/main/java/liquibase/ext/clickhouse/sqlgenerator/SqlGeneratorUtil.java:45-58, src/main/java/liquibase/ext/clickhouse/params/ParamsLoader.java:82-95
Cluster Management and Engine Selection
When cluster mode is active, the extension modifies the CREATE TABLE and ALTER TABLE statements to ensure consistency across the ClickHouse cluster.
- Cluster Clause: If
ClusterConfigis present,ON CLUSTER '{clusterName}'is injected into queries. - Engine Clause: Tables are created using
ReplicatedMergeTreewith a ZooKeeper path prefix and replica name. Otherwise, a standardMergeTreeis used. - Mutations: Status updates (e.g., checksum updates, tagging) use
ALTER TABLE ... UPDATEorDELETEwithSETTINGS mutations_sync = 1to ensure the operation completes synchronously.
Sources: src/main/java/liquibase/ext/clickhouse/sqlgenerator/SqlGeneratorUtil.java:51-60, src/main/java/liquibase/ext/clickhouse/sqlgenerator/UpdateChangeSetChecksumClickHouse.java:58-61
Key Operations
Locking Mechanism
Locking is handled via the DATABASECHANGELOGLOCK table. Initialization involves clearing existing rows using an asynchronous mutation followed by an insert.
Database Tagging
Tagging in ClickHouse is implemented by updating the TAG column for the most recently executed changeset. It uses a subquery to identify the latest record by DATEEXECUTED and ORDEREXECUTED.
ALTER TABLE `default`.DATABASECHANGELOG
ON CLUSTER 'my_cluster'
UPDATE TAG='v1.0'
WHERE DATEEXECUTED=(SELECT DATEEXECUTED FROM DATABASECHANGELOG ORDER BY DATEEXECUTED DESC, ORDEREXECUTED DESC LIMIT 1)
AND ORDEREXECUTED=(SELECT ORDEREXECUTED FROM DATABASECHANGELOG ORDER BY DATEEXECUTED DESC, ORDEREXECUTED DESC LIMIT 1)
SETTINGS mutations_sync = 1
Sources: src/main/java/liquibase/ext/clickhouse/sqlgenerator/TagDatabaseGeneratorClickhouse.java:62-85
Checksum Maintenance
When a changeset's checksum needs updating, the extension issues an ALTER TABLE ... UPDATE statement targeting specific ID, AUTHOR, and FILENAME coordinates.
Sources: src/main/java/liquibase/ext/clickhouse/sqlgenerator/UpdateChangeSetChecksumClickHouse.java:54-65
Summary
The DatabaseChangeLog management system in this extension adapts Liquibase's core tracking logic to ClickHouse's unique architecture. By leveraging ReplicatedMergeTree for storage and mutations_sync for state updates, it provides a reliable way to manage schema evolution across distributed ClickHouse clusters.