clickhouse提供了update和delete的删除能力,但是和常规的例如mysql,redis这种立即见效的能力不一样。在clickhouse中这种操作称为mutation操作。
ALTER TABLE [db.]table DELETE WHERE filter_expr
ALTER table test delete where id = 111;
ALTER table test update name = 'aa',age = 18 where id IN (SELECT id FROM test where eventTime = '2020-02-22');
当执行了update或者delete操作后,数据的存储目录会发生变化。每一个原有的数据存储目录都会新增一个同名目录,这个同名目录后面会加上一个后缀,并且会多出一个txt文件。 例如: 202102_1_1_0目录会多出一个202102_1_1_0_2目录; 多个一个mutation_2.txt文件。
这个txt文件是一个日志文件,记录了update或者delete操作的执行语句和时间。
以数据删除为例:数据的删除过程,是以数据表的每个分区目录为单位,将所有目录重写为新的目录。数据在重写的过程中会将需要删除的数据移除掉。旧的数据目录并不会立即删除,而是会被标记为非激活状态(active为0)。当到MergeTree引擎下一次合并动作触发时,这些非激活目录才会被真正的物理删除。
因此,删除和更新操作,是一个很重的操作。不适合单条处理。
亲测一条sql更新400万条记录中的一个字段时,数据库会崩溃。在后续超过2小时的时间,数据库访问都是超时,偶尔可以执行最简单的sql。没办法,只能把表删除了重建。
原因:
执行了批量更新字段 — 这是作死的操作
ALTER table java4all.atable on cluster ck update sampleTag = ‘white’ where sequenceId IN (
SELECT raba.sequenceId FROM java4all.atable raba where raba.partnerCode = ‘demo’ and raba.appName = ‘autoTest’
);
sql效果:更新400万条数据,每条数据更新一个字段值。
后果:ck集群在3小时内,无法响应请求,sql执行都是time out。
查询:SELECT * FROM system.mutations where database = ‘forseti’;时is_done一直是0;三小时内查询都是这样子。
删除: KILL MUTATION where database = ‘forseti’; 执行此操作,试图kill掉此次mutation操作。
结果:kill掉后,查看日志,发现依旧再刷错误日志。
删除表:直接把表删除。
结果:还是持续报错,此时一直报找不到分区parts,merge parts出错。意味着,尽管kill 了mutation和删了表,后台还在持续去执行mutation操作。
集群情况:双副本都挂掉了。
重启解决。
结论:彻底禁用update操作!!!