在前文ClickHouse从单节点升级为副本集群中提到,CK的副本是依赖Replicated*MergeTree表引擎来实现的,我们之前的单节点的CK上有些表还是MergeTree引擎的,没办法直接添加副本需要先转换表引擎。
网上找了下比较全的是这一份文档,他这里介绍了4种办法
https://kb.altinity.com/altinity-kb-setup-and-maintenance/altinity-kb-converting-mergetree-to-replicated/
Use INSERT INTO foo_replicated SELECT * FROM foo .
Create table aside and attach all partition from the existing table then drop original table (uses hard links don’t require extra disk space). ALTER TABLE foo_replicated ATTACH PARTITION ID 'bar' FROM 'foo' You can easily auto generate those commands using a query like: SELECT DISTINCT 'ALTER TABLE foo_replicated ATTACH PARTITION ID \'' || partition_id || '\' FROM foo;' from system.parts WHERE table = 'foo';
Do it ‘in place’ using some file manipulation. see the procedure described here: https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/#converting-from-mergetree-to-replicatedmergetree
Do a backup of MergeTree and recover as ReplicatedMergeTree. https://github.com/AlexAkulov/clickhouse-backup/blob/master/Examples.md#how-to-convert-mergetree-to-replicatedmegretree
前3种方法都还比较通俗易懂,我们这里都演示一下,第四种方法还需要使用backup,这种操作还不熟悉,以后再试试。
INSERT INTO
这种方法应该是最通俗易懂的,使用replicated引擎建新表,使用insert into向新表插入数据,重命名旧表和新表:
# 建好新的replicated引擎表后开始插入数据INSERT INTO TEST.FAILED_APIS_SHARD_RE SELECT * FROM TEST.FAILED_APIS_SHARD# 重命名旧表为bkrename table TEST.FAILED_APIS_SHARD to TEST.FAILED_APIS_SHARD_BK# 将新表进行重命名rename table TEST.FAILED_APIS_SHARD_RE to TEST.FAILED_APIS_SHARD
我用一个小数据量的表做了下实验没啥问题。
ATTACH PARTITION FROM
ALTER TABLE table2 [ON CLUSTER cluster] ATTACH PARTITION partition_expr FROM table1
这个就直接采用从老表将分区copy到新表,问题就是如果分区很多的话,手工不好操作,文档里面给出了一个基于system.parts表自动生成所有partition id并执行的例子:
SYSTEM STOP MERGES;#这一步可以在远程CK客户端执行,这只是把后面需要执行的命令打出来SELECT DISTINCT 'ALTER TABLE foo_replicated ATTACH PARTITION ID \'' || partition_id || '\' FROM foo;' from system.parts WHERE table = 'foo' AND active;┌─concat('ALTER TABLE foo_replicated ATTACH PARTITION ID \'', partition_id, '\' FROM foo;')─┐│ ALTER TABLE foo_replicated ATTACH PARTITION ID '202111' FROM foo; ││ ALTER TABLE foo_replicated ATTACH PARTITION ID '202201' FROM foo; │└───────────────────────────────────────────────────────────────────────────────────────────┘# 这一步必须在有ck-client的服务器上执行,这一步会执行所有的allter table ATTACH PARTITIONk的操作clickhouse-client -q "SELECT DISTINCT 'ALTER TABLE foo_replicated ATTACH PARTITION ID \'' || partition_id || '\' FROM foo;' from system.parts WHERE table = 'foo' format TabSeparatedRaw" |clickhouse-client -mnSYSTEM START MERGES;
这个操作就是充分利用了CK ATTACH PARTITION FROM的特性直接copy分区过去,官方文档特别进行了说明这种操作原始表的数据也会被保留。 Note that data will be deleted neither from table1 nor from table2.
ALTER TABLE ATTACH PARTITION
这是官方文档建议的操作:
重命名现有的 MergeTree 表,然后使用旧名称创建 ReplicatedMergeTree 表。
将数据从旧表移动到新表(/var/lib/clickhouse/data/db_name/table_name/)目录内的 ‘detached’ 目录中。
然后在其中一个副本上运行ALTER TABLE ATTACH PARTITION,将这些数据片段添加到工作集中。
前二步没啥问题,最后一步有点坑,在partition比较多的时候,ALTER TABLE ATTACH PARTITION这个命令没办法一次将所有的分区全部attach上。这个时候github是你的朋友:
https://github.com/ClickHouse/ClickHouse/issues/8183
有大佬提供的这样一个命令,需要在CK客户端进行执行:
clickhouse-client --format=TSVRaw -q"select 'ALTER TABLE ' || database || '.' || table || ' ATTACH PARTITION ID \'' || partition_id || '\';\n' from system.detached_parts group by database, table, partition_id order by database, table, partition_id;" | clickhouse-client -mn
原理就是从system.detached_parts表中拿到所有的detached_parts,然后都attach上去。
小结
CK并没办法直接将MegreTree引擎向ReplicatedMergeTree引擎的转换,还是先重新建表,然后迁移数据。第一种insert into的办法最简单明了,但不确定大数量下的效率,其他二种方案都是迁移老的表的partitions到新的表。因为单节点也可以建replicated的表,最开始规划的时候还是最好尽量避免建MegreTree的表,直接建ReplicatedMergeTree方便后面进行扩展。




