All Products
Search
Document Center

ApsaraDB for ClickHouse:FAQ

Last Updated:Jun 08, 2026

This topic covers frequently asked questions about ApsaraDB for ClickHouse, including instance selection, scaling, connections, data migration, queries, and storage.

ApsaraDB for ClickHouse vs. community version

ApsaraDB for ClickHouse fixes stability bugs in the community version and provides resource queues to set resource usage priorities by user role.

Recommended versions for ApsaraDB for ClickHouse

ApsaraDB for ClickHouse uses stable LTS kernel versions from the open-source community. New versions are typically available after a three-month stabilization period. We recommend version 21.8 or later. Version Feature Comparison.

Single-replica vs. master-replica instances

  • A single-replica instance does not have a replica node for each shard node and therefore provides no high availability. Its data security relies on the multi-replica storage of the underlying cloud disk, making it a highly cost-effective option.

  • A master-replica instance provides a replica node for each shard node. If a primary node fails, the corresponding replica node provides disaster recovery.

Insufficient resources error

Try purchasing resources in a different zone within the same region. Zones in the same region are connected via VPC with negligible latency.

Factors affecting horizontal scaling time

Horizontal scaling involves data migration, so the process takes longer for instances with more data.

Impact of scaling

To ensure data consistency during data migration, the instance enters a read-only state during scaling.

Horizontal scaling recommendations

Horizontal scaling is slow. If your cluster lacks performance, prioritize vertical scaling. Vertical scaling and horizontal scaling for Community Edition clusters.

Port descriptions

Protocol

Port number

Description

TCP

3306

Use this port to connect to ApsaraDB for ClickHouse using the clickhouse-client tool. Connect to ClickHouse using a command line interface.

HTTP

8123

Use this port to connect to ApsaraDB for ClickHouse using JDBC for application development. Connect to ClickHouse using JDBC.

HTTPS

8443

Use this port to access ApsaraDB for ClickHouse over HTTPS. Connect to ClickHouse using the HTTPS protocol.

SDK connection ports for Alibaba Cloud ClickHouse

Language

HTTP

TCP

Java

8123

3306

Python

Go

SDKs for Go and Python

The recommended SDKs are listed in Third-Party Client Libraries.

Resolve the "connect timed out" error

Try these solutions:

  • Check network connectivity. Use ping to check network reachability and telnet to verify that database ports 3306 and 8123 are open.

  • Verify your ClickHouse whitelist configuration. Configure a whitelist.

  • Confirm the public IP address of your client machine. On an office network, this address can change frequently, so use an IP lookup service such as whatsmyip.

Cannot connect to external tables

In versions 20.3 and 20.8, the system automatically validates the connection when you create an external table. Successful table creation confirms network connectivity. If table creation fails, common reasons include:

  • The target endpoint and ClickHouse are not in the same VPC, which prevents network connectivity.

  • The MySQL server uses a whitelist. You must add ClickHouse to the MySQL whitelist.

For Kafka external tables, if a table is created successfully but queries return no data, the cause is often that the data in Kafka fails to parse according to the table schema. The error message will indicate the exact location of the parsing failure.

Troubleshoot connection issues

Common causes of connection failures and their solutions:

  • Cause: The network environment is misconfigured. You can connect over an internal network only if your application and the instance are in the same VPC. If they are in different VPCs, you must enable a public endpoint and connect over the public network.

    Solution: Enable public network access. Apply for and release public IP addresses.

  • Cause: The client's IP address is not in the instance whitelist.

    Solution: Add the client IP to the whitelist. Configure a whitelist.

  • Cause: The security group for your ECS instance blocks traffic on the required port.

    Solution: Update the ECS security group rules. Security group operation guide.

  • Cause: A corporate firewall is blocking the connection.

    Solution: Modify your firewall rules to allow outbound traffic to the instance.

  • Cause: The username or password in the connection string contains special characters, such as !@#$%^&*()_+=. The client might not interpret these characters correctly, which causes a connection failure.

    Solution: You must URL-encode any special characters in the connection string. The encoding rules are as follows:

    ! : %21
    @ : %40
    # : %23
    $ : %24
    % : %25
    ^ : %5e
    & : %26
    * : %2a
    ( : %28
    ) : %29
    _ : %5f
    + : %2b
    = : %3d

    For example, if your password is ab@#c, the encoded password in the connection string must be ab%40%23c.

  • Cause: ApsaraDB for ClickHouse automatically provisions a pay-as-you-go Server Load Balancer (SLB) instance for your cluster. If your Alibaba Cloud account has overdue payments, the SLB instance may be suspended, making your ApsaraDB for ClickHouse instance inaccessible.

    Solution: Check your Alibaba Cloud account for overdue payments and pay any outstanding balance to restore the service.

Handle ClickHouse timeout issues

ApsaraDB for ClickHouse provides various timeout-related parameters for the HTTP and TCP protocols.

HTTP protocol

The HTTP protocol is the most common method for interacting with ApsaraDB for ClickHouse in production environments. Clients such as the official JDBC driver, Alibaba Cloud DMS, and DataGrip all use the HTTP protocol in the background. The default port for the HTTP protocol is 8123.

  • How to handle distributed_ddl_task_timeout issues

    • This parameter specifies the wait time for distributed DDL queries (with an ON CLUSTER clause) to execute. The default value is 180 seconds. You can run the following command in Alibaba Cloud DMS to set this as a global parameter. The new setting takes effect after a cluster restart.

      set global on cluster default distributed_ddl_task_timeout = 1800;

      Because ZooKeeper manages and executes distributed DDL tasks asynchronously in a queue, a timeout indicates that the task is still queued for execution, not that it has failed. Do not resubmit the task.

  • How to handle max_execution_time timeout issues

    • This parameter specifies the maximum execution time for a query. The default value is 7200 seconds on the Alibaba Cloud DMS platform and 30 seconds for clients like the JDBC driver and DataGrip. When this time limit is reached, ClickHouse automatically cancels the query. You can override this setting at the query level. For example: select * from system.numbers settings max_execution_time = 3600. Alternatively, you can run the following command in Alibaba Cloud DMS to set it as a global parameter.

      set global on cluster default max_execution_time = 3600;
  • How to handle socket_timeout issues

    • This parameter specifies the wait time for a listening socket to return a result over the HTTP protocol. The default value is 7200s on the DMS platform, and 30s for the JDBC driver and DataGrip. This parameter is not a ClickHouse system parameter, but a JDBC parameter for the HTTP protocol. However, it affects the effectiveness of the max_execution_time parameter setting because it determines the client-side time limit for waiting for a result. Therefore, when you adjust the max_execution_time parameter, you must also adjust the socket_timeout parameter to a value slightly higher than max_execution_time. To set this parameter, add the socket_timeout property to the JDBC connection string. The value is specified in milliseconds. For example: 'jdbc:clickhouse://127.0.0.1:8123/default?socket_timeout=3600000'.

  • Client hangs when connecting directly to the ClickHouse server IP address

    • When an ECS instance connects to a ClickHouse server across security groups, a silent connection failure may occur. This failure can happen if the IP address of the ClickHouse server is not in the security group whitelist of the ECS instance that runs the JDBC client. If a long-running query is executed, routing issues may prevent the delivery of response packets to the client, which causes the client to hang.

      Similar to resolving transient connection issues with an SLB instance, enabling send_progress_in_http_headers can resolve most of these problems. In the rare cases where this setting does not work, add the IP address of the ClickHouse server to the security group whitelist of the ECS instance where the client is running.

TCP protocol

The TCP protocol is most commonly used for interactive analysis with the native command-line tool of ClickHouse. The common port for Community Edition clusters is 3306. Because the TCP protocol includes keep-alive packets, it does not experience socket-level timeouts. You only need to manage the distributed_ddl_task_timeout and max_execution_time parameters. You can set them using the same method as for the HTTP protocol.

Resolve the "Connection refused (localhost:9000)" error

  • Problem: After creating a dictionary in an Alibaba Cloud ClickHouse instance, running a query returns the following error: "Code: 210. DB::NetException: Connection refused (localhost:9000). (NETWORK_ERROR) (version 23.8.16.1)".

  • Cause: Alibaba Cloud ClickHouse uses port mapping. The port shown in the console (for example, 9000) is the load balancer port, not the actual node port. To access the instance with localhost, use the actual node port, not the load balancer port.

  • Solution: Access the actual node port. For example, change localhost:9000 to localhost:3003. The table below shows common port mappings for the Community Edition.

    Load balancer port

    Actual node port

    3306

    3003

    9000

    3003

    8123

    3002

    9004

    3005

    8443

    3006

Prometheus port inaccessible on ApsaraDB for ClickHouse

  • Problem: You have configured Prometheus parameters for your ApsaraDB for ClickHouse cluster, but you cannot access the specified Prometheus port. For example, the telnet cc-xxxx.clickhouse.ads.aliyuncs.com:port-number command fails.

  • Cause: The connection address provided in the console points to a load balancer, while the Prometheus service runs on the underlying ApsaraDB for ClickHouse nodes. The load balancer is not configured to forward traffic on custom ports to these nodes.

  • Solution: Connect directly to the IP addresses of the underlying nodes to access Prometheus. Run the following command to retrieve the IP addresses of the underlying nodes. Then, use one of the retrieved IP addresses to connect to the Prometheus port.

    SELECT * FROM system.clusters;

OOM errors during OSS data import

Common cause: High memory usage.

To resolve this issue, do one of the following:

How to resolve the "too many parts" error

ClickHouse generates a data part for each write operation. Writing a single row or small amounts of data at a time creates an excessive number of data parts, which heavily burdens merge operations and queries. The "too many parts" error occurs because ClickHouse enforces internal limits to prevent this. If this error occurs, increase your write batch size. If you cannot adjust the batch size, increase the value of the merge_tree.parts_to_throw_insert parameter in the console.

Why are DataX imports slow?

Common causes and solutions:

  • Cause 1: Suboptimal parameter configuration. ClickHouse performs best with a large batch size and a small number of concurrent operations. A single batch can often contain tens or even hundreds of thousands of rows, depending on your average row size. As a general guideline, you can estimate based on 100 bytes per row, but you should adjust this value based on your actual data characteristics.

    Solution: Set the number of concurrent operations to 10 or fewer. Experiment with different parameter values to find the optimal configuration for your workload.

  • Cause 2: Insufficient resources in the DataWorks exclusive resource group. The ECS instances in the exclusive resource group may be undersized. Insufficient CPU or memory can limit the number of concurrent operations and the available network egress bandwidth. Likewise, setting a large batch size on a machine with limited memory can trigger frequent Java garbage collection (GC) in the DataWorks process, which slows down performance.

    Solution: Check the DataWorks output logs for the ECS instance specifications.

  • Cause 3: The bottleneck is at the data source.

    Solution: In the DataWorks output logs, search for the totalWaitReaderTime and totalWaitWriterTime metrics. If totalWaitReaderTime is significantly higher than totalWaitWriterTime, the bottleneck is on the read side (the data source), not the write side.

  • Cause 4: Use of a public network endpoint. A public network endpoint has limited bandwidth and is unsuitable for high-performance data import or export operations.

    Solution: Switch to a VPC network endpoint.

  • Cause 5: Presence of dirty data. Normally, data is written in a batch. However, if dirty data is encountered, the current batch write fails. DataX then falls back to a row-by-row insertion mode. This fallback generates excessive data parts and drastically reduces write performance.

    You can use the following two methods to check for dirty data.

    • Check for error messages. If the log contains a Cannot parse error, this indicates dirty data.

      You can use the following SQL query to find exceptions.

      SELECT written_rows, written_bytes, query_duration_ms, event_time, exception
      FROM system.query_log
      WHERE event_time BETWEEN '2021-11-22 22:00:00' AND '2021-11-22 23:00:00' AND lowerUTF8(query) LIKE '%insert into <table_name>%' and type != 'QueryStart' and exception_code != 0
      ORDER BY event_time DESC LIMIT 30;
    • Monitor the batch row count. If the number of rows per batch drops to 1, this strongly indicates that DataX has encountered dirty data and switched to row-by-row mode.

      You can use the following SQL query to check the row count.

      SELECT written_rows, written_bytes, query_duration_ms, event_time
      FROM system.query_log
      WHERE event_time BETWEEN '2021-11-22 22:00:00' AND '2021-11-22 23:00:00' AND lowerUTF8(query) LIKE '%insert into <table_name>%' and type != 'QueryStart'
      ORDER BY event_time DESC LIMIT 30;

    Solution: Identify and correct or remove the dirty data from the data source.

Row count mismatch after Hive import

Perform the following checks:

  1. Check the query_log system table for errors during the import. If any errors exist, data loss has likely occurred.

  2. Check if your table engine supports deduplication. For example, if you use the ReplacingMergeTree table engine, the number of rows in ClickHouse may be lower than in Hive because this engine removes duplicates.

  3. Verify the accuracy of the number of rows in the Hive source, as the source's initial count may be inaccurate.

Row count mismatch between ClickHouse and Kafka

Check the following:

  1. Check the query_log system table for errors that occurred during the import. If errors are present, data loss may have occurred.

  2. Check if your table engine performs data deduplication. For example, the ReplacingMergeTree engine removes duplicate entries, which lowers the row count in ClickHouse compared to Kafka.

  3. Check if the kafka_skip_broken_messages parameter is enabled in your Kafka external table configuration. If enabled, ClickHouse skips messages that fail to parse, reducing the row count in ClickHouse compared to Kafka.

Data import with Spark and Flink

Import data from an existing ClickHouse

Use one of these methods:

MaterializeMySQL sync error: The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires

This error indicates that the MaterializeMySQL engine stopped synchronizing for an extended period, causing the MySQL binary log to expire and be purged.

To resolve this issue, delete the affected database and then recreate it in ApsaraDB for ClickHouse.

Why do tables stop synchronizing and why is the sync_failed_tables field in the system.materialize_mysql system table not empty when you use the MaterializeMySQL engine to synchronize MySQL data?

Common cause: You ran a MySQL Data Definition Language (DDL) statement that ApsaraDB for ClickHouse does not support during synchronization.

Solution: Follow these steps to resynchronize the MySQL data.

  1. Delete the table that stopped synchronizing.

    DROP TABLE <table_name> ON cluster default;
    Note

    In this command, table_name is the name of the table that stopped synchronizing. If the table is a distributed table, you must delete both the distributed table and its local table.

  2. Restart the synchronization process.

    ALTER database <database_name> ON cluster default MODIFY SETTING skip_unsupported_tables = 1;
    Note

    In this command, <database_name> is the name of the synchronized database in ApsaraDB for ClickHouse.

Resolving the error "Too many partitions for single INSERT block (more than 100)"

This error occurs when a single INSERT operation attempts to write to more partitions than allowed by the max_partitions_per_insert_block parameter, which defaults to 100. In ClickHouse, each write operation creates a data part. A partition can contain one or more data parts. If an INSERT statement writes data to too many distinct partitions at once, it generates too many data parts, which can strain merge and query operations. To prevent performance degradation, ClickHouse enforces this limit.

To resolve this issue, you can adjust your partitioning strategy or modify the max_partitions_per_insert_block parameter.

  • Adjust the table schema, modify the partitioning method, or ensure that a single insert operation does not exceed the partition limit.

  • If your use case requires writing to many partitions at once, you can increase the max_partitions_per_insert_block limit based on your data volume. Use the following syntax to modify the parameter:

    Single-node instance

    SET GLOBAL max_partitions_per_insert_block = XXX;

    Multi-node instance

    SET GLOBAL ON cluster DEFAULT max_partitions_per_insert_block = XXX;
    Note

    The ClickHouse community recommends the default value of 100. Setting this value too high can degrade performance. After your bulk data import is complete, you can revert the parameter to its default value.

Memory limit exceeded error for insert into select

Querying CPU and memory usage

The system.query_log system table provides CPU and memory usage statistics for each query.

Troubleshooting memory limit errors

The ClickHouse server tracks memory usage at multiple levels. For a single query, a memory tracker aggregates the memory usage of all its query threads. This tracker then reports to an overall memory tracker. The solution depends on the specific error you encounter.

  • An error with Memory limit (for query) means the query failed because it consumed too much memory, exceeding its limit of 70% of the total instance memory capacity. To resolve this, perform a vertical upgrade to increase the instance memory capacity.

  • An error with Memory limit (for total) means the overall memory usage on the instance has exceeded the system-wide limit of 90% of the total instance memory capacity. This error can result from high query concurrency or resource-intensive background asynchronous tasks, such as primary key merge tasks that run after data writes. First, try reducing query concurrency. If the error persists, perform a vertical upgrade to increase the instance memory capacity.

SQL query memory limit error in Enterprise Edition

Cause: Each node in an Alibaba Cloud ApsaraDB for ClickHouse Enterprise Edition cluster has 32 ClickHouse compute units (CCUs) and 128 GB of memory. The operating system uses some of this memory, leaving approximately 115 GB for query execution. By default, a single SQL query runs on one node. A memory limit error occurs if a query uses more than 115 GB of memory.

Note

A cluster's maximum CCU limit determines its number of nodes. If the maximum CCU limit is greater than 64, the number of nodes in an Enterprise Edition cluster is: Maximum CCU limit / 32. If the maximum CCU limit is 64 or less, the Enterprise Edition cluster has two nodes.

Solution: Append the following SETTINGS clause to your SQL statement to enable parallel execution across multiple nodes. This technique distributes the memory load, which can prevent the memory limit error.

SETTINGS 
    allow_experimental_analyzer = 1,
    allow_experimental_parallel_reading_from_replicas = 1;

Excessive memory consumption in GROUP BY

Set the max_bytes_before_external_group_by parameter to limit memory consumption for GROUP BY operations. Note that the allow_experimental_analyzer setting affects whether this parameter takes effect.

Handling Concurrency Limit Exceeded errors

The default maximum query concurrency for a server is 100. Modify this value in the console:

  1. Log in to the ApsaraDB for ClickHouse console.

  2. On the Clusters page, select Clusters of Community-compatible Edition, and then click the target cluster ID.

  3. In the left-side navigation pane, click Parameter Configuration.

  4. On the Parameter Configuration page, click the edit icon in the Parameter Value column for the max_concurrent_queries parameter.

  5. Enter the new value in the dialog box and click OK.

  6. Click Submit Parameters.

  7. Click OK.

Inconsistent query results when data writes have stopped

Problem description: When you query data using select count(*), only about half of the total data is returned, or the results fluctuate.

Consider the following solutions:

  • Check if you are using a multi-node cluster. In a multi-node cluster, you must create a distributed table. Write to and query this table for consistent results. Otherwise, each query may hit a different shard. Create a distributed table.

  • Check if you are using a master-replica cluster. In a master-replica cluster, use tables with a Replicated series table engine to synchronize data between replicas. Otherwise, each query may hit a different replica, leading to inconsistent results. Table engines.

Invisible tables and fluctuating query results

Common causes and solutions:

  • Cause 1: The table creation process is incorrect. A ClickHouse distributed cluster does not have native distributed DDL semantics. If you use a create table statement in a self-managed ClickHouse cluster, the statement may return a success message, but the table is created only on the currently connected server. When you connect to a different server, the table is not visible.

    Solution:

    1. When you create a table, use the create table <table_name> on cluster default statement. The on cluster default clause broadcasts the statement to all nodes in the default cluster.

      CREATE TABLE test ON cluster default (a UInt64) Engine = MergeTree() ORDER BY tuple();
    2. Create another table that uses the distributed table engine on top of the test table.

      CREATE TABLE test_dis ON cluster default AS test Engine = Distributed(default, default, test, cityHash64(a));
  • Cause 2: The ReplicatedMergeTree table is misconfigured. The ReplicatedMergeTree table engine is an enhanced version of the MergeTree table engine that provides master-replica synchronization. On a single-replica instance, you can only create tables with the MergeTree engine. On a master-replica instance, you must create tables with the ReplicatedMergeTree engine.

    Solution: When you create a table in a master-replica instance, use ReplicatedMergeTree('/clickhouse/tables/{database}/{table}/{shard}', '{replica}') or ReplicatedMergeTree() to configure the ReplicatedMergeTree table engine. The arguments in ReplicatedMergeTree('/clickhouse/tables/{database}/{table}/{shard}', '{replica}') are part of a fixed template and should not be modified.

Timestamp data discrepancies

Run SELECT timezone() to check if the timezone is the local timezone. If not, set the 'timezone' configuration item to the local timezone. See Modify running parameter values for configuration items for instructions.

Table not found after creation

This issue commonly occurs when a DDL statement is executed on only one node.

To resolve this issue, ensure the DDL statement includes the on cluster clause. Table creation syntax.

No new data in Kafka external tables

First, run a select * from query on the Kafka external table. If the query fails, check the error message. This is often due to a data parsing failure. If the query returns results, check that the fields of the destination table (the underlying storage table for the Kafka external table) and the Kafka external table match. If the data write fails, the fields do not match. For example:

insert into <destination table> as select * from <Kafka external table>;

Client time and time zone mismatch

This issue occurs when the use_client_time_zone setting is configured with an incorrect time zone.

Data not visible after a write operation?

Symptom: After you write data to a table, subsequent queries cannot find the data.

Cause: Possible causes include the following:

  • The schemas of the distributed table and the local tables are inconsistent.

  • After data is written to a distributed table, the distribution of temporary files is incomplete.

  • After data is written to one replica in a master-replica cluster, replica synchronization is incomplete.

Analysis and solutions:

Inconsistent schemas

Query the system.distribution_queue system table to check for errors that occurred during writes to the distributed table.

Incomplete file distribution

Cause analysis: In a multi-node ApsaraDB for ClickHouse cluster, if your application connects to the database using a domain name and runs an INSERT statement on a distributed table, a front-end Server Load Balancer (SLB) routes the request to a random node in the cluster. The node that receives the request writes part of the data to its local disk and stores the rest as temporary files. These files are then asynchronously distributed to the other nodes. If a query is executed before this distribution process is complete, it may not return the undistributed data.

Solution: If your application requires strong read-after-write consistency, add the settings insert_distributed_sync = 1 clause to your INSERT statement. This setting switches the INSERT operation to a synchronous mode. The statement returns a success message only after the data is distributed to all nodes.

Important
  • Enabling this setting increases the execution time of INSERT statements because the operation must wait for data distribution to complete. Evaluate the trade-off between data consistency and write performance for your application.

  • This setting applies at the cluster level and should be used with caution. First, test this setting on a single query. After verifying the results, apply it at the cluster level only if your business requires it.

  • To apply this setting to a single query, append it to the end of the statement. For example:

    INSERT INTO <table_name> values() settings insert_distributed_sync = 1;
  • To apply this setting at the cluster level, configure it in the user.xml file. Configure user.xml parameters.

Incomplete replica synchronization

Cause analysis: In a master-replica ApsaraDB for ClickHouse cluster, when you run an INSERT statement, the cluster executes the operation on one randomly chosen replica. The data is then asynchronously synchronized to the other replica. If a subsequent SELECT query is routed to the replica that has not yet completed synchronization, the query may not return the expected data.

Solution: If your application requires strong read-after-write consistency, add the settings insert_quorum = 2 clause to your INSERT statement. This setting forces replica synchronization to run in synchronous mode. The INSERT statement returns a success message only after data synchronization is complete on both replicas.

Important

Consider the following when you use this parameter:

  • This setting increases the execution time of INSERT statements because the operation must wait for replica synchronization to complete. Evaluate the trade-off between data consistency and write performance for your application.

  • After this parameter is set, INSERT operations must wait for synchronization between replicas to succeed. This means that if a replica is unavailable, all write operations configured with insert_quorum = 2 will fail, which conflicts with the reliability guarantee of a dual-replica setup.

  • This setting applies at the cluster level and should be used with caution. First, test this setting on a single query. After verifying the results, apply it at the cluster level only if your business requires it.

  • To apply this setting to a single query, append it to the end of the statement. For example:

    INSERT INTO <table_name> values() settings insert_quorum = 2;
  • To apply this setting at the cluster level, configure it in the user.xml file. Configure user.xml parameters.

Why TTL does not delete expired data

Symptom

A TTL has been correctly configured for a table, but expired data in the table is not automatically deleted, meaning the TTL setting is not taking effect.

Troubleshooting Steps

  1. Check if the table's TTL setting is reasonable.

    Set the TTL based on your business requirements. We recommend setting the TTL at the day level and avoiding settings at the second or minute level, such as TTL event_time + INTERVAL 30 SECOND.

  2. Check the materialize_ttl_after_modify parameter.

    This parameter controls whether a new TTL rule applies to existing data after you run anALTER MODIFY TTL statement. The default value is 1 (enabled). A value of 0 means the rule applies only to new data, and existing data is not affected by the TTL.

    • Check the parameter setting

      SELECT * FROM system.settings WHERE name like 'materialize_ttl_after_modify';
    • Modify the parameter setting

      Important

      This command scans all existing data and can create a high resource load. Use it with caution.

      ALTER TABLE $table_name MATERIALIZE TTL;
  3. Diagnose the partition cleanup strategy.

    When the ttl_only_drop_parts parameter is set to 1, ClickHouse deletes a data part only when all rows within that part have expired.

    • Check the ttl_only_drop_parts parameter setting

      SELECT * FROM system.merge_tree_settings WHERE name LIKE 'ttl_only_drop';
    • Check the partition expiration status

      SELECT partition, name, active, bytes_on_disk, modification_time, min_time, max_time, delete_ttl_info_min, delete_ttl_info_max FROM system.parts c WHERE database = 'your_dbname' AND TABLE = 'your_tablename' LIMIT 100;
      • delete_ttl_info_min: The minimum datetime key value used for the TTL DELETE rule in this part.

      • delete_ttl_info_max: The maximum datetime key value used for the TTL DELETE rule in this part.

    • If the partition and TTL rules do not align, some data might not be cleaned up promptly. The following explains how partition and TTL rules interact.

      • If the partition and TTL rules are aligned (for example, partitioning by day and setting a daily TTL), ClickHouse can determine expiration based on the partition ID and delete an entire partition at once. This is the most efficient strategy. For optimal performance, we recommend combining a partitioning strategy (such as by day) with ttl_only_drop_parts=1 to efficiently delete expired data.

      • If the rules are not aligned and ttl_only_drop_parts = 1, ClickHouse checks the TTL information of each part. A part is deleted only after all its data has exceeded the delete_ttl_info_max timestamp.

      • If the rules are not aligned and ttl_only_drop_parts = 0, ClickHouse must scan the data within each part to find and delete individual expired rows. This is the most resource-intensive strategy.

  4. Control the merge trigger frequency.

    Expired data is deleted asynchronously during merges, not in real time. You can control the merge frequency with the merge_with_ttl_timeout parameter or force TTL materialization by using the ALTER TABLE ... MATERIALIZE TTL statement.

    • Check the parameter

      SELECT * FROM system.merge_tree_settings WHERE name = 'merge_with_ttl_timeout';
      Note

      The unit is seconds. The default value for an online instance is 7200 seconds (2 hours).

    • Modify the parameter

      If merge_with_ttl_timeout is set too high, the TTL merge trigger frequency decreases, delaying the cleanup of expired data. You can lower this parameter to increase the cleanup frequency. For details, see Parameter description.

  5. Check the thread pool parameter settings.

    TTL data removal occurs during the part merge phase and is limited by the max_number_of_merges_with_ttl_in_pool (default: 2 for online instances) and background_pool_size (default: 16 for online instances) parameters.

    • Query current background thread activity

      SELECT * FROM system.metrics WHERE metric LIKE 'Background%';

      The BackgroundPoolTask metric indicates the number of tasks currently active in the background pool.

    • Modify the parameters

      If your other parameter settings are correct and CPU utilization is low, consider increasing the max_number_of_merges_with_ttl_in_pool parameter based on your business needs, for example, from 2 to 4, or from 4 to 8. If this does not resolve the issue, consider increasing the background_pool_size parameter.

      Important

      You must restart the cluster if you adjust the max_number_of_merges_with_ttl_in_pool parameter. You do not need to restart the cluster when you increase the background_pool_size parameter, but you must restart the cluster when you decrease the background_pool_size parameter.

  6. Check if the table schema and partition design are reasonable.

    If a table is not partitioned effectively or if the partition granularity is too coarse, TTL cleanup efficiency decreases. For efficient cleanup, we recommend matching the partition granularity with the TTL granularity (for example, setting both to a daily interval). For details, see Best practices.

  7. Check if the cluster has sufficient disk space.

    Background merge operations trigger TTL cleanup and require available disk space. Large data parts or insufficient disk space (for example, usage exceeding 90%) can prevent merge operations and their subsequent TTL deletions.

  8. Check other system parameters in system.merge_tree_settings.

    • merge_with_recompression_ttl_timeout: The minimum delay before a merge with a recompression TTL can repeat. By default, this means TTL rules are applied to a table at least every 4 hours. If you need to apply TTL rules more frequently, lower this value.

    • max_number_of_merges_with_ttl_in_pool: This parameter controls the maximum number of threads available for TTL tasks. If the number of ongoing merge tasks with TTL in the background thread pool exceeds this value, ClickHouse does not schedule new merge tasks with TTL.

Slow optimize tasks

An optimize task is CPU- and disk-intensive. It competes for resources with concurrent queries, so it may run slowly under heavy load.

Primary key merge failure after optimize

A primary key merge must meet the following two prerequisites to function correctly.

  • The ORDER BY key must include the partition key of the storage table. A primary key merge does not occur across different partitions.

  • For a distributed table, the ORDER BY key must include the sharding key, which is determined by the hash algorithm. A primary key merge does not occur across different nodes.

The following table describes common optimize commands and their behavior.

Command

Description

optimize table test;

This command attempts to select and merge MergeTree data parts but may return without performing any action. Even if executed, it does not guarantee a complete primary key merge for all records in the table. This command is generally not recommended.

optimize table test partition tuple();

This command targets a specific partition and merges all its data parts. It may return without performing any action. When the task finishes, it consolidates all data within the specified partition into a single data part, completing the primary key merge for that partition. However, the merge does not include data written while the task is running. The task does not run again if the partition already consists of a single data part.

Note

For tables without a partition key, the default partition is tuple().

optimize table test final;

This command forces a merge of all partitions in the table. It re-merges partitions even if they already consist of a single data part. This is useful for forcing the deletion of records that have exceeded their Time to Live (TTL). This operation is the most resource-intensive and may still return without performing a merge.

For any of these optimize commands, you can set the optimize_throw_if_noop parameter. If this parameter is enabled, the command throws an exception if it performs no merge, so you can determine whether the task was actually performed.

Data TTL ineffective after optimize

Here are common causes and their solutions.

  • Cause 1: Data TTL eviction occurs during the primary key merge phase. If a data part is not merged for an extended period, the system cannot evict the expired data within it.

    Solution:

    • You can manually trigger a merge task by running optimize final or optimize a specific partition.

    • When creating a table, you can set parameters such as merge_with_ttl_timeout and ttl_only_drop_parts to merge data parts that contain expired data more frequently.

  • Cause 2: If a table's TTL is modified or added, existing data parts may have missing or incorrect TTL information. This may also prevent the eviction of expired data.

    Solution:

    • You can regenerate TTL information by running alter table materialize ttl.

    • You can update the TTL information by running optimize partition.

Updates and deletes not taking effect after OPTIMIZE

ApsaraDB for ClickHouse executes update and delete operations asynchronously. Monitor progress by querying the system.mutations system table.

Adding, deleting, or modifying columns with DDL

To modify a local table, execute a DDL statement. For a distributed table, the procedure depends on whether data is currently being written to it.

  • If no data is being written to the table, modify the local table first, and then modify the distributed table.

  • If data is being written to the table, the procedure depends on the type of modification.

    Type

    Actions

    Adding a nullable column

    1. Modify the local table.

    2. Modify the distributed table.

    Modifying a column's data type (to a convertible type)

    Dropping a nullable column

    1. Modify the distributed table.

    2. Modify the local table.

    Adding a non-nullable column

    1. Stop writing data.

    2. Execute SYSTEM FLUSH DISTRIBUTED on the distributed table.

    3. Modify the local table.

    4. Modify the distributed table.

    5. Resume writing data.

    Dropping a non-nullable column

    Renaming a column

Slow and stuck DDL operations

Global DDL execution is sequential, and complex queries can cause deadlocks.

Try these solutions:

  • Wait for the operation to complete.

  • Try terminating the query in the console.

Distributed DDL task timeout error

Modify the default timeout by running set global on cluster default distributed_ddl_task_timeout=xxx, where xxx is the timeout in seconds. Modify cluster parameters.

Syntax error: "set global on cluster default"

  • Cause 1: The ClickHouse client parses syntax. However, set global on cluster default is a server-side syntax. If the client version is incompatible with the server, the client blocks this statement.

    Solution:

    • Use a tool that does not perform client-side syntax parsing. Examples include JDBC-based tools like DataGrip and DBeaver.

    • Write a JDBC program to execute the statement.

  • Cause 2: In the set global on cluster default key = value; statement, the value is a string but is not enclosed in quotation marks.

    Solution: Enclose the string value in quotation marks.

Recommended BI tool

We recommend Quick BI.

Recommended data query IDEs

DataGrip, DBeaver.

Vector search support

Yes. ApsaraDB for ClickHouse supports vector search. Relevant resources:

Resolve the ON CLUSTER is not allowed for Replicated database error

If your cluster is an Enterprise Edition cluster and the table creation statement includes ON CLUSTER default, you may encounter the ON CLUSTER is not allowed for Replicated database error. This occurs in some minor versions. Upgrade your instance to the latest version. Upgrade minor engine versions.

Resolve the Double-distributed IN/JOIN subqueries is denied (distributed_product_mode = 'deny') error

Problem: If you use a multi-node Community Edition cluster, you might encounter the errorException: Double-distributed IN/JOIN subqueries is denied (distributed_product_mode = 'deny').  when a query uses JOIN or IN to join multiple distributed tables.

Cause: When a query joins multiple distributed tables, it can cause query amplification. For example, in a three-node cluster, a join query between two distributed tables expands into 3 x 3 subqueries on the underlying local tables. This consumes significant resources and increases latency. To prevent this, the system blocks these queries by default.

How it works: By replacing the IN or JOIN operator with GLOBAL IN or GLOBAL JOIN, you instruct the engine to execute the right-side subquery on a single node. The result is stored in a temporary table, which is then broadcast to all other nodes to complete the join locally.

Impact of using GLOBAL IN or GLOBAL JOIN:

  • The temporary table is sent to all remote servers. Avoid this strategy for large datasets.

  • Using GLOBAL IN or GLOBAL JOIN with the remote() function can produce incorrect results. This is because the subquery, which should run on the external instance, instead runs on the current instance.

    For example, you run the following statement on instance_a to query data from the external instance cc-bp1wc089c****.

    SELECT *
    FROM remote('cc-bp1wc089c****.clickhouse.ads.aliyuncs.com:3306', `default`, test_tbl_distributed1, '<your_Account>', '<YOUR_PASSWORD>')
    WHERE id GLOBAL IN
        (SELECT id
         FROM test_tbl_distributed1);

    In this case, instance_a executes the subquery SELECT id FROM test_tbl_distributed1 to generate a temporary table, let's call it temp_table_A. The data from temp_table_A is then sent to the external instance cc-bp1wc089c**** for the final query. The external instance cc-bp1wc089c**** ultimately runs the statement SELECT * FROM default.test_tbl_distributed1 WHERE id IN (temp_table_A);.

    The problem arises from the source of the data in the temporary table.

    Based on the description above, the final statement executed by instance cc-bp1wc089c**** is SELECT * FROM default.test_tbl_distributed1 WHERE id IN (temporary table A);. However, the condition set in temporary table A is generated on instance a. In this example, instance cc-bp1wc089c**** should have executed SELECT * FROM default.test_tbl_distributed1 WHERE id IN (SELECT id FROM test_tbl_distributed1 );, and the condition set should have originated from instance cc-bp1wc089c****. Therefore, the use of GLOBAL IN or GLOBAL JOIN causes the subquery to retrieve the condition set from an incorrect source, which leads to an incorrect result.

Solutions:

Solution 1: Modify your application's SQL code to manually replace IN or JOIN with GLOBAL IN or GLOBAL JOIN.

For example, change this statement:

SELECT * FROM test_tbl_distributed WHERE id IN (SELECT id FROM test_tbl_distributed1);

to:

SELECT * FROM test_tbl_distributed WHERE id GLOBAL IN (SELECT id FROM test_tbl_distributed1);

Solution 2: Modify the distributed_product_mode or prefer_global_in_and_join system parameter so the system automatically converts IN or JOIN to GLOBAL IN or GLOBAL JOIN.

distributed_product_mode

Run the following statement to set distributed_product_mode to global. This setting automatically converts standard IN or JOIN operations into GLOBAL IN or GLOBAL JOIN when necessary.

SET GLOBAL ON cluster default distributed_product_mode='global';

Usage

  • Purpose: Controls how ClickHouse handles distributed subqueries.

  • Values:

    • deny (default): Prohibits distributed IN and JOIN subqueries and throws the "Double-distributed IN/JOIN subqueries is denied" exception.

    • local: Rewrites the subquery to use the local table on the target shard, preserving a standard IN or JOIN operator.

    • global: Converts IN or JOIN queries to GLOBAL IN or GLOBAL JOIN queries.

    • allow: Permits standard IN and JOIN subqueries, which may cause query amplification.

  • Applicable scenarios: Applies only to queries that use IN or JOIN to join multiple distributed tables.

prefer_global_in_and_join

prefer_global_in_and_join

Run the following statement to set the prefer_global_in_and_join parameter to 1. This setting automatically converts standard IN or JOIN operations into GLOBAL IN or GLOBAL JOIN.

SET GLOBAL ON cluster default prefer_global_in_and_join = 1;

Usage

  • Purpose: Controls the behavior of the IN and JOIN operators.

  • Values:

    • 0 (default): Prohibits distributed IN and JOIN subqueries and throws the "Double-distributed IN/JOIN subqueries is denied" exception.

    • 1: Enables distributed IN and JOIN subqueries by automatically converting them to GLOBAL IN or GLOBAL JOIN queries.

  • Applicable scenarios: Applies only to queries that use IN or JOIN to join multiple distributed tables.

View table disk space

To view the disk space used by each table, run the following query.

SELECT table, formatReadableSize(sum(bytes)) as size, min(min_date) as min_date, max(max_date) as max_date FROM system.parts WHERE active GROUP BY table; 

View cold data size

The following is an example query:

SELECT * FROM system.disks;

Query data in cold storage

Use the following query:

SELECT * FROM system.parts WHERE disk_name = 'cold_disk';

Move partition data to cold storage

To move a data partition to cold storage, run the following statement:

ALTER TABLE table_name MOVE PARTITION partition_expr TO DISK 'cold_disk';

Gaps in monitoring data

Common causes include:

  • A query triggering an OOM error.

  • An instance restart triggered by a configuration change.

  • An instance restart following an upgrade or downgrade.

Smooth upgrade without data migration

Whether a ClickHouse cluster supports a smooth upgrade depends on its creation date. Clusters purchased after December 1, 2021 support an in-place upgrade without data migration. Clusters purchased before that date require data migration. Upgrade the major engine version.

Common system tables

The following table describes common system tables and their functions.

Parameter

Description

system.processes

Contains information about SQL statements that are currently running.

system.query_log

Contains a log of executed SQL statements.

system.merges

Contains information about merge operations on the cluster.

system.mutations

Contains information about mutation operations on the cluster.

Modify system-level parameters

System-level parameters map to settings in the config.xml file. To modify them:

  1. Log in to the ApsaraDB for ClickHouse console.

  2. On the Clusters page, select Clusters of Community-compatible Edition, and then click the target cluster ID.

  3. In the left-side navigation pane, click Parameter Configuration.

  4. On the Parameter Configuration page, click the edit icon in the Parameter Value column for the max_concurrent_queries parameter.

  5. Enter the new value in the dialog box and click OK.

  6. Click Submit Parameters.

  7. Click OK.

After clicking OK, the clickhouse-server process automatically restarts, causing a transient disconnection of about 1 minute.

Modify user-level parameters

User-level parameters correspond to configuration items in the users.xml file. To modify a parameter, run the following statement.

SET global ON cluster default ${key}=${value};

Unless specified otherwise, the change takes effect immediately.

Modify quota

Specify the quota parameter in the settings of an execution statement:

settings max_memory_usage = XXX;

Varying CPU and memory usage across nodes

In a dual-replica or single-replica multi-node cluster, the write node has higher CPU usage and memory usage than other nodes during heavy write operations. Usage balances out across the nodes once the data is synchronized.

View detailed system logs

  • Problem description:

    How to view detailed system logs to troubleshoot errors or identify potential issues.

  • Solution:

    1. Check the text_log.level parameter for your cluster and do one of the following:

      1. If text_log.level is empty, text logging is disabled. To enable it, set a value for this parameter.

      2. If text_log.level has a value, verify that the log level meets your requirements. If not, modify the parameter to the desired level.

      Configure config.xml parameters.

    2. Connect to the target database. Connect to a database.

    3. Run the following statement to view and analyze the logs.

      SELECT * FROM system.text_log;

Resolve network connectivity issues

If the destination cluster and data source are in the same VPC and region, verify that the IP address of each is in the other's whitelist.

  • To configure the ClickHouse whitelist, see Set a Whitelist.

  • For other data sources, see their respective product documentation.

If the preceding conditions are not met, first establish connectivity by using a suitable network solution. Then, add the IP address of each to the other's whitelist.

Scenario

Solution

hybrid cloud connectivity

Network Interconnection Between On-Premises and Cloud

cross-region and cross-account VPC connectivity

Cross-account VPC-to-VPC Connection

same-region, different-VPC connectivity

Use Cloud Enterprise Network to Achieve Same-region VPC Connectivity (Basic Edition)

cross-region and cross-account VPC connectivity

Use Cloud Enterprise Network to Achieve Cross-region and Cross-account VPC-to-VPC Connection (Basic Edition)

public network connectivity

Use Internet NAT Gateway SNAT to Access the Internet

address conflict

Use VPC NAT Gateway to Resolve Address Conflicts

Community to Enterprise Edition migration

Yes, you can migrate a ClickHouse Community Edition cluster to an Enterprise Edition cluster.

You can migrate data between Enterprise Edition and Community Edition clusters using the remote function or by exporting and importing data files. Migrate data from a self-managed ClickHouse cluster to Alibaba Cloud ClickHouse Community-Compatible Edition.

Inconsistent schemas during data migration

Problem description

Data migration requires consistent database and table schemas across all shards. Otherwise, some databases or tables may fail to migrate.

Solutions

  • The schema of a MergeTree table (not an inner table of a materialized view) is inconsistent across shards.

    Investigate whether your business logic is causing the schema discrepancies between shards:

    • If you expect the table schemas to be identical across all shards, you must recreate the tables to ensure consistency.

    • If your business logic intentionally uses different table schemas across shards, Submit a ticket to contact technical support for assistance.

  • The inner table of a materialized view is inconsistent across shards.

    • Solution 1: Rename the inner tables and explicitly point the materialized view and distributed table to the target MergeTree table. The following procedure uses the original materialized view up_down_votes_per_day_mv as an example.

      1. List tables that are not present on every node. NODE_NUM = Number of shards × Number of replicas.

        SELECT database,table,any(create_table_query) AS sql,count() AS cnt
        FROM cluster(default, system.tables)
        WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA')
        GROUP BY  database, table
        HAVING cnt != <NODE_NUM>;
      2. Identify the materialized views that have an incorrect number of inner tables.

        SELECT substring(hostName(),38,8) AS host,*
        FROM cluster(default, system.tables)
        WHERE uuid IN (<UUID1>, <UUID2>, ...);
      3. Disable the default cluster synchronization behavior. This step is required for ApsaraDB for ClickHouse clusters but not for self-managed ClickHouse clusters. Then, rename the inner table to ensure consistency across all nodes. To reduce operational risk, obtain the IP address of each node, connect to port 3005, and run the following statements on each node individually.

        SELECT count() FROM mv_test.up_down_votes_per_day_mv;
        SET enforce_on_cluster_default_for_ddl=0; 
        RENAME TABLE `mv_test`.`.inner_id.9b40675b-3d72-4631-a26d-25459250****` TO `mv_test`.`up_down_votes_per_day`;
      4. Drop the materialized view. Run the following statements on each node individually.

        SELECT count() FROM mv_test.up_down_votes_per_day_mv;
        SET enforce_on_cluster_default_for_ddl=0; 
        DROP TABLE mv_test.up_down_votes_per_day_mv;
      5. Create a new materialized view that explicitly points to the renamed inner table. Run the following statements on each node individually.

        SELECT count() FROM mv_test.up_down_votes_per_day_mv;
        SET enforce_on_cluster_default_for_ddl=0; 
        CREATE MATERIALIZED VIEW mv_test.up_down_votes_per_day_mv TO `mv_test`.`up_down_votes_per_day`
        (
            `Day` Date,
            `UpVotes` UInt32,
            `DownVotes` UInt32
        ) AS
        SELECT toStartOfDay(CreationDate) AS Day,
               countIf(VoteTypeId = 2) AS UpVotes,
               countIf(VoteTypeId = 3) AS DownVotes
        FROM mv_test.votes
        GROUP BY Day;

        Note: You must explicitly define the columns of the target table in the materialized view definition. Do not rely on type inference from the SELECT statement, as this can cause unexpected errors. For example, if a column named tcp_cn is calculated using an aggregate state function like sumIfState in the SELECT statement, you must define its type in the target table as an AggregateFunction, such as AggregateFunction(sum, Float64).

        Correct usage

        CREATE MATERIALIZED VIEW net_obs.public_flow_2tuple_1m_local TO net_obs.public_flow_2tuple_1m_local_inner
        (
         ... 
        tcp_cnt AggregateFunction(sum, Float64),
        ) AS
        SELECT
        ...
        sumIfState(pkt_cnt, protocol = '6') AS tcp_cnt,
        FROM net_obs.public_flow_5tuple_1m_local
        ...

        Incorrect usage

        CREATE MATERIALIZED VIEW net_obs.public_flow_2tuple_1m_local TO net_obs.public_flow_2tuple_1m_local_inner AS
        SELECT
        ...
        sumIfState(pkt_cnt, protocol = '6') AS tcp_cnt,
        FROM net_obs.public_flow_5tuple_1m_local
        ...
    • Solution 2: Rename the inner tables, rebuild the materialized views on all nodes, and then migrate the data from the old inner tables.

    • Solution 3: Implement a dual-write strategy for the materialized views and allow 7 days for the data to synchronize.

SQL statement failure in Enterprise Edition 24.5 or later

By default, Enterprise Edition 24.5 or later instances use the new query analyzer. This analyzer delivers better performance but may not be backward-compatible with some legacy SQL statements. If you encounter a parsing error, revert to the legacy analyzer. Learn more about the new analyzer.

SET allow_experimental_analyzer = 0;

Suspend a cluster

The suspend feature is only available for Enterprise Edition clusters. ClickHouse Community Edition clusters cannot be suspended. To suspend an Enterprise Edition cluster, go to the Enterprise Edition Clusters page. Select the target region in the top-left corner. In the cluster list, find the target cluster and click image> Suspend in the Actions column.

Convert a MergeTree table to ReplicatedMergeTree

Problem description

Users unfamiliar with ClickHouse may mistakenly create tables with the MergeTree engine in a multi-replica cluster. This prevents data from being synchronized between the replica nodes of each shard. Consequently, queries on the corresponding distributed table can return inconsistent results. To resolve this issue, you must convert the MergeTree table to a ReplicatedMergeTree table.

Solution

ClickHouse does not provide a DDL statement to directly change a table's storage engine. To convert a MergeTree table to a ReplicatedMergeTree table, you must create a new table with the ReplicatedMergeTree engine and then import the data from the original table.

For example, assume you have a MergeTree table named table_src and its corresponding distributed table named table_src_d in a multi-replica cluster. To convert this MergeTree table to a ReplicatedMergeTree table, follow these steps:

  1. Create the target ReplicatedMergeTree table, table_dst, and its corresponding distributed table, table_dst_d. CREATE TABLE.

  2. Import the data from the MergeTree table table_src into table_dst_d. You can use one of the following two methods.

Note
  • Both methods query source data from the local MergeTree table.

  • If the data volume is small, insert data directly into the distributed table table_dst_d to distribute the data evenly.

  • If the data in the original MergeTree table table_src is already balanced across all nodes and the data volume is large, you can insert the data directly into the local ReplicatedMergeTree table table_dst on each node.

  • If the dataset is large, the import process may take a long time. When you use the remote() function, make sure to configure an appropriate timeout value.

Use the remote function

  1. Connect to ClickHouse through DMS.

  2. Obtain the IP address of each node.

    SELECT 
        cluster,
        shard_num,
        replica_num,
        is_local,
        host_address
    FROM system.clusters
    WHERE cluster = 'default';
    
  3. Import the data by using the remote function.

    Sequentially pass the IP addresses from the previous step to the remote() function and run the statement for each.

    INSERT INTO  table_dst_d SELECT * FROM remote('node1', db.table_src) ;

    For example, if the IP addresses of two nodes are 10.10.0.165 and 10.10.0.167, run the following INSERT statements separately:

    INSERT INTO table_dst_d SELECT * FROM remote('10.10.0.167', default.table_src) ;
    INSERT INTO table_dst_d SELECT * FROM remote('10.10.0.165', default.table_src) ;

    Running the statements for all node IP addresses converts the MergeTree table to a ReplicatedMergeTree table.

Use local tables

If you have an ECS instance with the ClickHouse client installed in your VPC, you can log on to each node separately to perform the following operations.

  1. Connect to ClickHouse using the command line interface.

  2. Obtain the IP address of each node.

    SELECT 
        cluster,
        shard_num,
        replica_num,
        is_local,
        host_address
    FROM system.clusters
    WHERE cluster = 'default';
  3. Import the data.

    Log on to each node sequentially by using its IP address and run the following statement.

    INSERT INTO table_dst_d SELECT * FROM db.table_src ;

    Running the statement on all nodes converts the MergeTree table to a ReplicatedMergeTree table.

Execute multiple SQL statements in the same session

Setting a unique session_id ensures the ClickHouse server maintains a consistent context for requests with the same session ID. This lets you execute multiple SQL statements in a single session. This example shows how to do this with the ClickHouse Java Client (V2).

  1. Add the dependency to the pom.xml file of your Maven project.

    <dependency>
        <groupId>com.clickhouse</groupId>
        <artifactId>client-v2</artifactId>
        <version>0.8.2</version>
    </dependency>
  2. Set a custom session ID in CommandSettings.

    package org.example;
    
    import com.clickhouse.client.api.Client;
    import com.clickhouse.client.api.command.CommandSettings;
    public class Main {
    
        public static void main(String[] args) {
            Client client = new Client.Builder()
                    .addEndpoint("endpoint") // Instance endpoint
                    .setUsername("username")   // Username
                    .setPassword("password")   // Password
                    .build();
    
            try {
                client.ping(10);
                CommandSettings commandSettings = new CommandSettings();
                // Set the session_id
                commandSettings.serverSetting("session_id","examplesessionid");
                // Set the max_block_size parameter for the session
                client.execute("SET max_block_size=65409 ",commandSettings);
                // Execute the queries
                client.execute("SELECT 1 ",commandSettings);
                client.execute("SELECT 2 ",commandSettings);
    
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                client.close();
            }
        }
    }

In this example, both SELECT statements run in the same session with a max_block_size of 65409. ClickHouse Java Client: Java Client | ClickHouse Docs.

Why FINAL deduplication fails with JOIN

Symptom

When you use the FINAL keyword to deduplicate query results, deduplication fails if the SQL statement contains a JOIN clause. As a result, duplicate data remains in the output. The following is an example SQL statement:

SELECT * FROM t1 FINAL JOIN t2 FINAL WHERE xxx;

Cause

This is a known, unpatched bug in ClickHouse. Deduplication fails because of a conflict between the execution logic of FINAL and JOIN. ClickHouse issue #8655.

Solution

  • Solution 1 (Recommended): Enable the experimental optimizer. Enable query-level FINAL by adding a setting to your query. This method does not require a table-level declaration. For example:

    If the original SQL statement is:

    SELECT * FROM t1 FINAL JOIN t2 FINAL WHERE xxx;

    Remove the FINAL keyword from the table name and append settings allow_experimental_analyzer = 1,FINAL = 1 to the statement. The revised statement is as follows:

    SELECT * FROM t1 JOIN t2 WHERE xxx  SETTINGS allow_experimental_analyzer = 1, FINAL = 1; 
    Important

    The allow_experimental_analyzer parameter is supported only in versions 23.8 and later. If you use an earlier version, upgrade before modifying the SQL statement. Upgrade a major engine version.

  • Solution 2 (Use with caution):

    1. Force a merge for deduplication by periodically running OPTIMIZE TABLE local_table_name FINAL. This merges data in advance but should be used with caution for large tables, as it incurs high I/O overhead.

    2. Modify the SQL query: Remove the FINAL keyword. Data deduplication then relies on querying the merged data.

    Important

    Use this approach with caution because this operation consumes significant I/O resources and can affect the performance of large tables.

Why are DELETE or UPDATE operations incomplete?

Symptom

When you perform data deletion (DELETE) or update (UPDATE) operations in an ApsaraDB for ClickHouse Community-compatible Edition cluster, the tasks remain incomplete for a long time.

Cause

Unlike synchronous operations in MySQL, the DELETE and UPDATE operations in an ApsaraDB for ClickHouse Community-compatible Edition cluster are asynchronous and are executed based on the Mutation mechanism. Therefore, the changes do not take effect in real time. The core process of a Mutation is as follows:

  1. Submit task: A user runs the ALTER TABLE ... UPDATE/DELETE command to generate an asynchronous task.

  2. Mark data: The system creates a mutation_*.txt file in the background to record the data range to be modified. The changes are not applied immediately.

  3. Rewrite in the background: ClickHouse gradually rewrites the affected data part and applies the changes during the merge process.

  4. Clean up old data: After the merge is complete, the old data blocks are marked for deletion.

Therefore, issuing too many Mutation operations in a short period can block tasks and leave DELETE and UPDATE operations incomplete. To prevent a backlog, run the following SQL statement to check for running Mutations before you issue a new one.

SELECT * FROM clusterAllReplicas('default', system.mutations) WHERE is_done = 0;

Solution

  1. Check whether an excessive number of Mutation tasks are running on the cluster.

    You can run the following SQL statement to view the current status of Mutations in the cluster:

    SELECT * FROM clusterAllReplicas('default', system.mutations) WHERE is_done = 0;
  2. If many Mutation tasks are running, use a privileged account to cancel some or all of them.

    • Cancel all Mutation tasks on a single table.

      KILL MUTATION WHERE database = 'default' AND table = '<table_name>'
    • Cancel a specific Mutation task.

      KILL MUTATION WHERE database = 'default' AND table = '<table_name>' AND mutation_id = '<mutation_id>'

      To obtain the mutation_id, run the following SQL statement:

      SELECT mutation_id, * FROM clusterAllReplicas('default', system.mutations) WHERE is_done = 0;

How to resolve the "Code: 241. DB::Exception: Memory limit (total) exceeded" error in ApsaraDB for ClickHouse Enterprise Edition?

  • Symptom: When you execute an SQL statement, you encounter the following error message, even though the total memory of your cluster exceeds the memory limit specified in the error message:

    Code: 241. DB::Exception: Memory limit (total) exceeded: would use 115.28 GiB (attempt to allocate chunk of 133791376 bytes), maximum: 115.20 GiB. OvercommitTracker decision: Query was selected to stop by OvercommitTracker.: While executing AggregatingTransform. (MEMORY_LIMIT_EXCEEDED) (version 24.2.2.16476 (official build))
  • Cause: In ApsaraDB for ClickHouse Enterprise Edition, a single node has a CCU limit (maximum of 32 CCUs, where 1 CCU is approximately equal to 1 vCore and 4 GiB of memory). If a single SQL query consumes more memory than the node's threshold, MemoryTracker intercepts the query. The default threshold is 0.9 times the total memory of the node. You can run the following SQL statement to query the threshold:

    SELECT *
    FROM system.server_settings
    WHERE name = 'max_server_memory_usage_to_ram_ratio';
  • Solution: Set the allow_experimental_parallel_reading_from_replicas parameter to 1. This distributes the data reading phase across multiple nodes, spreading the memory consumption. Enterprise Edition.

Why are query results inconsistent?

Symptom

In an ApsaraDB for ClickHouse Community-compatible Edition cluster, running the same SQL statement multiple times returns inconsistent results.

Cause

Inconsistent results for the same query in an ApsaraDB for ClickHouse Community-compatible Edition cluster can occur for two main reasons:

  • Queries target a local table in a multi-shard cluster.

    In a multi-shard cluster of ApsaraDB for ClickHouse Community-compatible Edition, you must create a distributed table in addition to local tables. In such clusters, the data write process is as follows:

    Data is first written to the distributed table, which then distributes the data to local tables on different shards for storage.

    When you query data, the data source varies based on the type of table being queried:

    • Querying a distributed table: The distributed table aggregates and returns data from the local tables on all shards.

    • Querying a local table: Each query returns data from the local table of a randomly selected shard, which causes inconsistent results.

  • A table in a two-replica cluster was not created by using a Replicated* series engine.

    In a two-replica cluster of ApsaraDB for ClickHouse Community-compatible Edition, tables must be created with a Replicated* series engine, such as the ReplicatedMergeTree engine, to enable data synchronization between replicas.

    If a table in a two-replica cluster is created without a Replicated* series engine, data is not synchronized between replicas, which can cause inconsistent query results.

Solution

  1. Determine the cluster type.

    Check the cluster information to determine whether your cluster is a multi-shard cluster, a two-replica cluster, or a multi-shard and two-replica cluster. Follow these steps:

    1. Log on to the ApsaraDB for ClickHouse console.

    2. In the upper-left corner of the page, select Clusters of Community-compatible Edition.

    3. In the cluster list, click the ID of the target cluster to open the cluster information page.

      View the Edition in the Cluster Properties section and the Node Groups in the Configuration Information section. You can determine the cluster type based on the following properties:

      • If the number of node groups is greater than 1, the cluster is a multi-shard cluster.

      • If the series is High-availability Edition, the cluster is a two-replica cluster.

      • If both conditions are met, the cluster is a multi-shard and two-replica cluster.

  2. Select a solution based on the cluster type.

    Multi-shard cluster

    Check the type of the queried table. If it is a local table, query the distributed table instead.

    If a distributed table does not exist, you must create one. Create a table.

    Two-replica cluster

    Check the CREATE TABLE statement for the target table. If its engine is not a Replicated* series engine, recreate the table. Create a table.

    Multi-shard and two-replica cluster

    Check the type of the queried table.

    If it is a local table, query the distributed table. If a distributed table does not exist, you must create one.

    If you are querying a distributed table, check whether the engine of the corresponding local table is a Replicated* series engine. If not, recreate the local table with a Replicated* series engine. Create a table.

Why ReplacingMergeTree fails deduplication after a forced merge?

Symptom

The ReplacingMergeTree engine in ClickHouse deduplicates data with the same primary key during the data merge process. However, after you force a data merge by running the following command, duplicate data with the same primary key may still exist:

optimize TABLE <table_name> FINAL ON cluster default;

Cause

The ReplacingMergeTree engine deduplicates data only on a single node. If data with the same primary key is distributed to different nodes because the sharding_key expression is not explicitly specified (by default, data is randomly allocated by using the rand() function), the engine cannot deduplicate the data across the cluster.

Solution

Recreate the local table and the distributed table. When you create the distributed table, set the sharding_key expression to the primary key of the local table. CREATE TABLE.

Important

You must recreate both the distributed table and the local table. Recreating only the distributed table affects only new data, leaving existing data unduplicated.