更新时间:2025-07-24 GMT+08:00

ClickHouse数据迁移

本章节为您介绍数据迁移能力。

使用场景

ClickHouse集群节点扩容后,需要使用数据迁移对数据进行迁移。

注意事项

  • 存在分区大于50GB的表不支持页面操作迁移,需要手工迁移。
  • 迁移表需要非空,且设置唯一分区字段。空表或多字段分区在创建任务时无法选择。
  • 冷热分离表涉及热盘数据和冷盘数据迁移,如果对冷数据查询频次不高或者冷数据查询性能要求不高,可以无需迁移。后续新扩容节点的热数据盘使用率会随着业务数据写入,慢慢接近旧节点的热数据盘使用率。如果需要频繁查询冷数据,且对冷数据查询有性能要求,可以迁移冷热分离表,迁移过程中冷数据迁移速率慢。
  • 每个数据表只能绑定一个任务。一个集群仅支持一个执行中的任务。
  • 本地表的数据库必须为atomic(默认)或ordinary,且表类型为Mergetree家族系列引擎的表(包括非复制表和复制表,不支持物化视图表)。
  • 本地表副本关系和cluster一致,有分布式表作为分片之间的关系。
  • 数据迁移过程中原表默认为只读状态。
  • 数据迁移的时候数据首先会保存在临时表中,执行的时候用迁移的数据表替换原表,该过程中可能读取到错误的数据,切换时间为秒级。
  • 数据迁移过程中可能由于集群问题导致此过程暂停,根据报错修复集群继续执行任务。
  • 数据迁移的时候,源节点和重分布节点必须存在相同表,这样才可以进行数据迁移。
  • 单节点不支持数据迁移。

新建数据迁移任务自动迁移

前提:存在分区数据表数据小于50GB。

  1. 登录表格存储服务管理控制台。
  2. 控制台左上角选择区域。
  3. 进入集群管理页面,选择集群进入集群详情页面。
  4. 单击数据迁移进入数据迁移管理页面。

    表1 数据迁移参数说明

    参数

    说明

    任务ID/名称

    新建迁移任务ID/名称。

    逻辑集群

    选取的逻辑集群名称。

    源节点

    数据存放的节点。

    重分布节点

    数据分布的节点。

    状态/进度

    数据分布的状态/进度。

    状态:初始化、运行中、已完成。

    创建时间

    创建数据任务的时间。

    执行开始时间

    启动数据任务的时间。

    更新时间

    修改数据任务的时间。

    操作

    • 启动:启动数据任务。
    • 修改:修改任务信息。
    • 取消:取消迁移任务。
    • 详情:任务详情页面。
    • 删除:删除任务。

  5. 单击左上角“新建任务”。

    1. 用户自定义任务名称(以字母开头)。
    2. 选择逻辑集群。
    3. 选择迁移百分比。
    4. 选择源节点。
    5. 选择重分布节点。
    6. 选择迁移的数据表。

  6. 选择后单击确定,完成新建任务。
  7. 单击操作列“启动”,任务启动。

手动迁移数据

前提条件:存在分区数据表数据大于50GB。

  • 步骤一:创分布式表和本地表
    1. 使用SSH工具访问目标集群。请参见ClickHouse手动安装客户端
    2. 进入命令窗口创建数据库。
      CREATE DATABASE IF NOT EXISTS test_fetch on cluster default_cluster;
    3. 使用数据库。
      USE test_fetch;
    4. 创建本地表。
      CREATE TABLE IF NOT EXISTS test_fetch.example_table on cluster default_cluster (d DateTime, a Int) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_fetch/example_table', '{replica}') PARTITION BY toYYYYMM(d) ORDER BY d;
    5. 创建分布式表。
      CREATE TABLE IF NOT EXISTS test_fetch.example_table_dist ON CLUSTER default_cluster (d DateTime, a Int) ENGINE = Distributed('default_cluster', 'test_fetch', 'example_table', rand());
    6. 在分片1分别给分布式表和本地表插入数据。此时各个分片都包含202306 202307 202308的数据,仅分片1包含202309 2023010的数据。
      INSERT INTO test_fetch.example_table_dist select '2023-06-20',rand64() from numbers(1000);
      INSERT INTO test_fetch.example_table_dist select '2023-07-20',rand64() from numbers(1000);
      INSERT INTO test_fetch.example_table_dist select '2023-08-20',rand64() from numbers(1000);
      INSERT INTO test_fetch.example_table select '2023-09-20',rand64() from numbers(1000);
      INSERT INTO test_fetch.example_table select '2023-10-20',rand64() from numbers(1000);
  • 步骤二:fetch partition进行分片间数据迁移(将数据从分片1迁移到分片2)
    1. 选择迁移的分片和表数据分区。
      SELECT
          partition AS `分区名称`,
          formatReadableSize(sum(data_uncompressed_bytes)) AS `未压缩大小`,
          formatReadableSize(sum(data_compressed_bytes)) AS `压缩后大小`,
          sum(rows) AS `总行数`
      FROM system.parts
      WHERE (active = 1) AND (database = 'test_fetch') AND (table = 'example_table')
      GROUP BY partition
      ORDER BY partition DESC;

      运行结果展示。

      ┌─分区名称─┬─未压缩大小─┬─压缩后大小─┬─总行数─┐
      │ 202308   │ 3.81 KiB   │ 1.98 KiB   │    488 │
      │ 202307   │ 4.12 KiB   │ 2.14 KiB   │    527 │
      │ 202306   │ 3.88 KiB   │ 2.02 KiB   │    496 │
      └──────────┴────────────┴────────────┴────────┘
    2. 在目标分片的任意节点使用fetch partition获取分区数据,然后attach分区获取源分片中202309的分区并拉取当前分片。
      ALTER TABLE test_fetch.example_table FETCH PARTITION '202309' FROM '/clickhouse/tables/1/test_fetch/example_table/';

      '/clickhouse/tables/1/test_fetch/example_table/ 参数中的1代表分片1,可以根据实际调整。

      将源分片获取的数据加载到当前分片。

      ALTER TABLE test_fetch.example_table ATTACH PARTITION '202309';

      迁移执行时,目标分区节点如果提示detached分区已存在,可以查询detached_parts确认分区是否存在。如果已存在且为冗余数据或脏数据,可以删除。如需保留,可以跳过此分区,迁移其他分区。

      SELECT * FROM system.detached_parts WHERE table = 'example_table' AND partition_id = '202309';
      ALTER TABLE test_fetch.example_table DROP DETACHED PARTITION '202309' SETTINGS allow_drop_detached = 1;
  • 步骤三:验证结果。
    1. 数据行数、数据内容采样检查。
      SELECT count() FROM test_fetch.example_table WHERE toYYYYMM(d) = '202309';
      SELECT * FROM test_fetch.example_table WHERE toYYYYMM(d) = '202309' order by a limit 10;

      结果展示:

    2. 去重数据,删除源分片对应分区。
      1. 方法一:连接源节点分片删除数据分区。
        ALTER TABLE test_fetch.example_table DROP PARTITION '202309';
      2. 方法二:detach数据。
        ALTER TABLE test_fetch.example_table DETACH PARTITION '202309';

        如果提示分区数据大于50G无法删除,执行设置以下参数,再次操作删除。

         set max_table_size_to_drop=0;
         set max_partition_size_to_drop=0;
      1. 删除源分片分区后,查询源分片中的分布式表、目标分片中本地表。
        SELECT count() FROM test_fetch.example_table_dist WHERE toYYYYMM(d) = '202309';
        SELECT count() FROM test_fetch.example_table WHERE toYYYYMM(d) = '202309';

修改数据迁移任务

  1. 登录表格存储服务管理控制台。
  2. 进入集群管理页面,选择集群进入集群详情页面。
  3. 单击数据迁移进入数据迁移管理页面。
  4. 单击操作列“修改”,进入修改任务页面。
  5. 修改参数后,单击确定。

查看任务详情

  1. 登录表格存储服务管理控制台。
  2. 进入集群管理页面,选择集群进入集群详情页面。
  3. 单击数据迁移进入数据迁移管理页面。
  4. 单击操作列“修改”,进入任务详情页面。
  5. 查看任务相关信息。

删除任务

  1. 登录表格存储服务管理控制台。
  2. 进入集群管理页面,选择集群进入集群详情页面。
  3. 单击数据迁移进入数据迁移管理页面。
  4. 单击操作列“删除”,弹出删除窗口,单击确定,删除任务。