
# ClickHouse数据迁移
本章节为您介绍数据迁移能力。
#### 使用场景
ClickHouse集群节点扩容后，需要使用数据迁移对数据进行迁移。
#### 注意事项
- 存在分区大于50GB的表不支持页面操作迁移，需要手工迁移。
- 迁移表需要非空，且设置唯一分区字段。空表或多字段分区在创建任务时无法选择。
- 冷热分离表涉及热盘数据和冷盘数据迁移，如果对冷数据查询频次不高或者冷数据查询性能要求不高，可以无需迁移。后续新扩容节点的热数据盘使用率会随着业务数据写入，慢慢接近旧节点的热数据盘使用率。如果需要频繁查询冷数据，且对冷数据查询有性能要求，可以迁移冷热分离表，迁移过程中冷数据迁移速率慢。
- 每个数据表只能绑定一个任务。一个集群仅支持一个执行中的任务。
- 本地表的数据库必须为atomic（默认）或ordinary，且表类型为Mergetree家族系列引擎的表（包括非复制表和复制表，不支持物化视图表）。
- 本地表副本关系和cluster一致，有分布式表作为分片之间的关系。
- 数据迁移过程中原表默认为只读状态。
- 数据迁移的时候数据首先会保存在临时表中，执行的时候用迁移的数据表替换原表，该过程中可能读取到错误的数据，切换时间为秒级。
- 数据迁移过程中可能由于集群问题导致此过程暂停，根据报错修复集群继续执行任务。
- 数据迁移的时候，源节点和重分布节点必须存在相同表，这样才可以进行数据迁移。
- 单节点不支持数据迁移。
 
#### 新建数据迁移任务自动迁移
前提条件：存在分区数据表数据小于50GB。
1. 登录[表格存储服务控制台](https://console.huaweicloud.com/cloudtable)。
2. 左上角选择区域。
3. 进入集群管理页面，选择集群进入集群详情页面。
4. 单击数据迁移进入数据迁移管理页面。 
   表1数据迁移参数说明 
   | 参数      | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   |:---|:---|
   | 任务ID/名称 | 新建迁移任务ID/名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
   | 逻辑集群    | 选取的逻辑集群名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | 源节点     | 数据存放的节点。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | 重分布节点   | 数据分布的节点。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | 状态/进度   | 数据分布的状态/进度。 状态：初始化、运行中、已完成。                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | 创建时间    | 创建数据任务的时间。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | 执行开始时间  | 启动数据任务的时间。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | 更新时间    | 修改数据任务的时间。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
   | 操作      | - 启动：启动数据任务。  - 修改：修改任务信息。  - 取消：取消迁移任务。  - 详情：任务详情页面。  - 删除：删除任务。   |
      
   
   
5. 单击左上角"新建任务"。 
   1. 用户自定义任务名称（以字母开头）。
   
   2. 选择逻辑集群。
   
   3. 选择迁移百分比。
   
   4. 选择源节点。
   
   5. 选择重分布节点。
   
   6. 选择迁移的数据表。
   
   
   
   
6. 选择后单击确定，完成新建任务。
7. 单击操作列"启动"，任务启动。
 
#### 手动迁移数据
前提条件：存在分区数据表数据大于50GB。
- 步骤一：创分布式表和本地表
  1. 使用SSH工具访问目标集群。请参见[ClickHouse手动安装客户端](https://support.huaweicloud.com/usermanual-cloudtable/cloudtable_01_0307.html#cloudtable_01_0307__section95431029171615)。
  
  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';
     ```
     ![](https://support.huaweicloud.com/usermanual-cloudtable/public_sys-resources/note_3.0-zh-cn.png)
     迁移执行时，目标分区节点如果提示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;
     ```
     结果展示：
     ![](https://support.huaweicloud.com/usermanual-cloudtable/zh-cn_image_0000002376542529.png "点击放大")
     
  
  2. 去重数据，删除源分片对应分区。
     1. 方法一：连接源节点分片删除数据分区。
        ```
        ALTER TABLE test_fetch.example_table DROP PARTITION '202309';
        ```
        
     
     2. 方法二：detach数据。
        ```
        ALTER TABLE test_fetch.example_table DETACH PARTITION '202309';
        ```
        ![](https://support.huaweicloud.com/usermanual-cloudtable/public_sys-resources/note_3.0-zh-cn.png)
        如果提示分区数据大于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. 登录[表格存储服务控制台](https://console.huaweicloud.com/cloudtable)。
2. 进入集群管理页面，选择集群进入集群详情页面。
3. 单击数据迁移进入数据迁移管理页面。
4. 单击操作列"修改"，进入修改任务页面。
5. 修改参数后，单击确定。
 
#### 查看任务详情
1. 登录[表格存储服务控制台](https://console.huaweicloud.com/cloudtable)。
2. 进入集群管理页面，选择集群进入集群详情页面。
3. 单击数据迁移进入数据迁移管理页面。
4. 单击操作列"修改"，进入任务详情页面。
5. 查看任务相关信息。
 
#### 删除任务
1. 登录[表格存储服务控制台](https://console.huaweicloud.com/cloudtable)。
2. 进入集群管理页面，选择集群进入集群详情页面。
3. 单击数据迁移进入数据迁移管理页面。
4. 单击操作列"删除"，弹出删除窗口，单击确定，删除任务。
 
