本文主要介绍数据如何在ClickHouse之间迁移。

前提条件

出于安全考虑,云数据库ClickHouse后台服务器无法直接访问公网,只能够访问同一VPC内的其他服务器。所以数据迁移前,请首先确认源头ClickHouse与目的ClickHouse之间是否网络通畅。
  • 如果2个集群都在阿里云上,且是在同一VPC内,直接使用remote函数进行迁移。
  • 如果2个集群都在阿里云上,但是属于不同VPC,首先需要将两个VPC网络连通,详细操作请参见连接VPC。网络连通完成后,使用remote函数进行数据迁移。
  • 如果源头集群不在阿里云上,例如在线下自建IDC内,首先需要将线下IDC与阿里云VPC连通,详细操作请参见连接本地IDC。网络连通完成后,使用remote函数进行数据迁移。
  • 如果无法进行网络连通操作,建议在源头ClickHouse将数据导出为文件,然后通过clickhouse-client将文件导入到云数据库ClickHouse。
  • 如果无法进行网络连通操作,但是已经有了Spark、Flink等基础设施,也可以尝试编写Spark、Flink job将源头数据读出,然后写入目的ClickHouse。

元数据的迁移

ClickHouse元数据的迁移,主要指进行建表DDL迁移。

如需安装clickhouse-client工具,请单击下载链接clickhouse-client,如何安装和使用请参见社区文档

步骤一:查看源头ClickHouse数据库集群的database列表
clickhouse-client --host="<old host>" --port="<old port>" --user="<old user name>" --password="<old password>" --query="SHOW databases"  > database.list

参数解释如下:

参数 描述
old host 源头ClickHouse数据库集群的地址。
old port 源头ClickHouse数据库集群的端口。
old user name 登录源头ClickHouse数据库集群的用户名,拥有数据库的读写权限。
old password 上述用户名对应的密码。
说明 system是系统数据库,不需要迁移,可以直接过滤掉。
步骤二:查看源头ClickHouse数据库集群中的table列表
clickhouse-client --host="<old host>" --port="<old port>" --user="<old user name>" --password="<old password>" --query="SHOW tables from <database_name>"  > table.list

<database_name>表示希望查看的database。其他参数描述可参见“步骤一:查看源头ClickHouse数据库集群的database列表“。

您也可以通过系统表直接查询所有database、table名称。

select distinct database, name from system.tables where database != 'system';
说明 查询到的表名中,如果有以 .inner. 开头的表,则它们是物化视图的内部表示,不需要迁移,可以直接过滤掉。
步骤三:导出源头ClickHouse的建表DDL
clickhouse-client --host="<old host>" --port="<old port>" --user="<old user name>" --password="<old password>" --query="SHOW CREATE TABLE <database_name>.<table_name>"  > table.sql
步骤四:将建表DDL导入到目的ClickHouse
clickhouse-client --host="<new host>" --port="<new port>" --user="<new user name>" --password="<new password>"  < table.sql
参数 描述
new host 云数据库ClickHouse集群地址。
new port 云数据库ClickHouse数据库集群端口。
new user name 登录云数据库ClickHouse数据库集群的用户名,拥有数据库的读写权限。
new password 上述用户名对应的密码。

通过remote函数进行数据迁移

  1. 将目的ClickHouse的网段,加入到源头ClickHouse的白名单中。

    可以在云数据库ClickHouse控制台查看目的ClickHouse的VPC网络,并且将该VPC的整个网段都加入到源头ClickHouse的白名单中。如果希望控制白名单的网段范围,避免潜在安全问题,那么可以通过如下SQL查询到ClickHouse的后台server IP,只将这几个IP加入源头ClickHouse的白名单中。

    select * from system.clusters;
  2. 在目的ClickHouse中,通过如下SQL进行数据迁移。
    insert into <new_database>.<new_table> select * from remote('old_endpoint', <old_database>.<old_table>, '<username>', '<password>');
    20.8版本优先使用remoteRaw函数进行数据迁移,如果失败可以申请小版本升级。
    insert into <new_database>.<new_table> select * from remoteRaw('old_endpoint', <old_database>.<old_table>, '<username>', '<password>');
    参数 描述
    new_database 目的ClickHouse中的数据库名。
    new_table 目的ClickHouse中的表名。
    old_endpoint 源头ClickHouse的endpoint。此处要填写的是VPC内endpoint,而不是公网endpoint。
    old_database 源头ClickHouse中的数据库名。
    old_table 源头ClickHouse中的表名。
    username 源头ClickHouse的用户名。
    password 源头ClickHouse的密码。

通过文件导出导入方式进行数据迁移

通过文件,将数据从源头ClickHouse数据库导出到目的ClickHouse。

通过CSV文件导出导入
  1. 将数据从源头ClickHouse数据库导出为CSV格式文件。
    clickhouse-client --host="<old host>" --port="<oldport>" --user="<old user name>" --password="<old password>"  --query="select * from <database_name>.<table_name> FORMAT CSV"  > table.csv
  2. 导入CSV文件到目的ClickHouse。
    clickhouse-client --host="<new host>" --port="<new port>" --user="<new user name>" --password="<new password>"  --query="insert into <database_name>.<table_name> FORMAT CSV"  < table.csv
通过linux pipe管道进行流式导出导入
clickhouse-client --host="<old host>" --port="<old port>" --user="<user name>" --password="<password>"  --query="select * from <database_name>.<table_name> FORMAT CSV" | 
clickhouse-client --host="<new host>" --port="<new port>" --user="<user name>" --password="<password>"   --query="INSERT INTO <database_name>.<table_name> FORMAT CSV"