Extension Architecture
Relevant source files
The following files were used as context for generating this wiki page:
- pom.xml
- src/main/java/liquibase/ext/clickhouse/database/ClickHouseDatabase.java
- src/main/java/liquibase/ext/clickhouse/params/ParamsLoader.java
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/SqlGeneratorUtil.java
- src/main/java/liquibase/ext/clickhouse/lockservice/ClickHouseLockService.java
- src/main/java/liquibase/ext/clickhouse/sqlgenerator/CreateDatabaseChangeLogTableClickHouse.java
- README.md
The Liquibase ClickHouse extension provides a specialized implementation of the Liquibase framework tailored for the ClickHouse OLAP database. It extends core Liquibase components to handle ClickHouse-specific SQL syntax, engine requirements, and cluster distribution capabilities. The architecture is designed to support both single-instance ClickHouse deployments and distributed cluster environments using Replicated engines.
Sources: pom.xml, README.md:1-5, src/main/java/liquibase/ext/clickhouse/database/ClickHouseDatabase.java:31-35
Core Database Implementation
The foundation of the extension is the ClickHouseDatabase class, which identifies the database and defines its technical constraints. It extends AbstractJdbcDatabase and integrates with the com.clickhouse.jdbc.ClickHouseDriver.
Key Technical Specifications
| Feature | Specification | Source |
|---|---|---|
| Short Name | clickhouse | ClickHouseDatabase.java:78 |
| Default Port | 8123 | ClickHouseDatabase.java:83 |
| Priority | PRIORITY_DATABASE | ClickHouseDatabase.java:55 |
| DDL in Transaction | Not Supported | ClickHouseDatabase.java:108 |
| Sequences | Not Supported | ClickHouseDatabase.java:103 |
| Current DateTime | toDateTime64(..., 3) | ClickHouseDatabase.java:41-43 |
The implementation includes a specialized getConnectionSchemaNameCallStatement which uses the ClickHouse-specific SELECT currentDatabase() query to identify the active schema.
Sources: src/main/java/liquibase/ext/clickhouse/database/ClickHouseDatabase.java:31-114
Cluster and Parameter Management
The extension supports a "Cluster Mode" that allows Liquibase to manage schema changes across a ClickHouse cluster. This is managed via the ParamsLoader and ClusterConfig components.
Configuration Logic
The extension attempts to load a configuration file named liquibaseClickhouse.conf. If present and valid, the extension operates in "cluster replicated clickhouse mode"; otherwise, it defaults to "single-instance mode".
The following properties must be defined for cluster mode:
clusterName: The name of the ClickHouse cluster.tableZooKeeperPathPrefix: The Zookeeper path for replicated tables.tableReplicaName: The replica identifier.
Sources: src/main/java/liquibase/ext/clickhouse/params/ParamsLoader.java:84-118, README.md:14-20
SQL Generation and Engines
SQL generation is customized to handle ClickHouse's table engine requirements and the ON CLUSTER clause. The SqlGeneratorUtil class serves as a helper to inject these clauses based on the loaded ClusterConfig.
Table Engine Selection
When creating Liquibase metadata tables (ChangeLog and Lock tables), the extension dynamically selects the engine:
- Single Mode:
ENGINE MergeTree() ORDER BY ID - Cluster Mode:
ENGINE ReplicatedMergeTree('{zkPath}', '{replica}') ORDER BY ID
Sources: src/main/java/liquibase/ext/clickhouse/sqlgenerator/SqlGeneratorUtil.java:47-54, src/main/java/liquibase/ext/clickhouse/sqlgenerator/CreateDatabaseChangeLogTableClickHouse.java:65-72
Liquibase Metadata Schema
The extension overrides the creation of the DATABASECHANGELOG table to use ClickHouse-compatible data types, such as DateTime64 for execution dates and UInt64 for execution order.
| Column | ClickHouse Type | Source |
|---|---|---|
| ID / AUTHOR / FILENAME | String | CreateDatabaseChangeLogTableClickHouse.java:53-55 |
| DATEEXECUTED | DateTime64 | CreateDatabaseChangeLogTableClickHouse.java:56 |
| ORDEREXECUTED | UInt64 | CreateDatabaseChangeLogTableClickHouse.java:57 |
| MD5SUM | Nullable(String) | CreateDatabaseChangeLogTableClickHouse.java:59 |
Lock Service Architecture
ClickHouse-specific locking is implemented in ClickHouseLockService. Unlike standard RDBMS, ClickHouse handles mutations and deletes differently, which affects how the lock table is initialized and checked.
The InitializeDatabaseChangeLogLockClickHouse generator ensures the lock table is prepared by performing a DELETE WHERE 1 with SETTINGS mutations_sync = 1 before inserting the initial lock record. This ensures that the lock state is consistent across the cluster.
Sources: src/main/java/liquibase/ext/clickhouse/lockservice/ClickHouseLockService.java:46-64, src/main/java/liquibase/ext/clickhouse/sqlgenerator/InitializeDatabaseChangeLogLockClickHouse.java:55-68
Summary of Extension Components
| Component | Responsibility | Source |
|---|---|---|
ClickHouseDatabase | Database identification and feature support flags. | ClickHouseDatabase.java |
ParamsLoader | Loading cluster configuration from HOCON/Typesafe files. | ParamsLoader.java |
SqlGeneratorUtil | Utility for appending ON CLUSTER and ENGINE clauses. | SqlGeneratorUtil.java |
ClickHouseLockService | Managing database change log locks via ClickHouse SQL. | ClickHouseLockService.java |
ModifyDataTypeClickHouse | No-op implementation to prevent Liquibase from resizing String columns. | ModifyDataTypeClickHouse.java:31-35 |
This architecture ensures that Liquibase remains functional in high-availability ClickHouse environments by leveraging the database's native replication and distributed DDL capabilities.
Sources: README.md:27-33, src/main/java/liquibase/ext/clickhouse/sqlgenerator/ModifyDataTypeClickHouse.java:31-35