ClickHouse集群同步执行ALTER TABLE DELETE的操作疑问咨询
问题解答
关于你的猜测是否正确
你的猜测完全正确:
- 带
ON CLUSTER的ALTER mutation类请求(DELETE/UPDATE),发起节点仅会将任务提交到每个分片的ZooKeeper队列、确认所有节点接收任务后就直接返回,mutations_sync参数在ON CLUSTER场景下暂不生效,不会等待所有副本实际执行完mutation任务,因此执行完立即查询会出现仍有旧数据的情况。
不带ON CLUSTER执行DELETE的同步范围
直接在集群某一个节点上执行不带ON CLUSTER的ALTER TABLE foo DELETE WHERE 1 SETTINGS mutations_sync = 2,会同步删除当前分片所有副本上的对应数据:
- Replicated系列表引擎的所有DDL、mutation任务都是基于ZooKeeper同步的,你在任意一个副本提交mutation任务,都会同步到同分片的所有其他副本执行。
- mutations_sync=2的含义是等待当前分片的所有副本都完成该mutation任务再返回,你测试时不管设0还是2查询其他副本都返回0行,是因为测试数据量小,mutation执行速度远快于你手动查询的速度,还没等你触发查询已经全量同步完成。
核心问题解答
1. 如何在ClickHouse集群上正确执行同步的ALTER TABLE .. DELETE操作
两种可行方案:
方案1:使用ON CLUSTER + 主动校验完成状态
- 执行集群级删除命令:
ALTER TABLE foo ON CLUSTER bar DELETE WHERE [删除条件] - 轮询全集群所有节点的
system.mutations系统表,确认对应mutation任务的状态:
SELECT * FROM cluster('bar', system, mutations) WHERE table = 'foo' AND command LIKE '%DELETE WHERE [删除条件]%'
当所有节点返回的is_done字段为1、parts_to_do字段为0时,代表全集群所有副本都已完成删除操作。
方案2:逐分片执行+mutations_sync=2
依次连接每个分片的任意一个副本,执行删除命令:
ALTER TABLE foo DELETE WHERE [删除条件] SETTINGS mutations_sync = 2
该命令执行时会等待当前分片所有副本完成删除再返回,所有分片执行完成后即实现全集群同步删除。
2. 不带ON CLUSTER、设置mutations_sync=2的DELETE是否会删除所有副本数据,如何验证
结论
会删除同一个分片下所有副本的对应数据,若要实现全集群所有分片删除,需要在每个分片都执行一次该命令。
验证方法
故意拉长mutation的执行时间,即可观测到同步过程:
- 调大测试数据量,比如生成1000万行以上、大小不低于2G的测试数据
- 临时调低节点mutation执行并发:
SET max_background_mutations = 1 - 提交删除命令后立即执行查询,查看各副本的mutation状态:
-- 查当前节点mutation状态 SELECT is_done, parts_to_do FROM system.mutations WHERE table = 'foo' AND command LIKE '%DELETE%'; -- 查同分片其他副本的mutation状态 SELECT is_done, parts_to_do FROM remote('其他副本地址', system, mutations) WHERE table = 'foo' AND command LIKE '%DELETE%';
当其他副本的is_done为0时,查询该副本的foo表仍可查询到旧数据,等is_done变为1后旧数据消失,即可验证同步逻辑。
内容的提问来源于stack exchange,提问作者aifilin
相关产品推荐
相关产品推荐

