ClickHouse 虽然是OLAP数据库,但是它也提供了行级数据删除的功能,你可以通过 ALTER TABLE xxx DELETE WHERE xxx 来实现 。
这个操作很重量级,即便删除1行数据,它也会重写整个分区,之前我专门写过一篇文章介绍过,传送门:《为什么删数据也提示空间不足呢?》。
从 ClickHouse v22.8 开始,提供了一种轻量级删除的功能:
DELETE FROM [db.]table [WHERE expr]
现在用一个示例说明它的用法:
--建表
CREATE TABLE test_cardinality_1 (a String, b String, c String)
ENGINE = MergeTree ORDER BY (a, b, c)
--写入数据
INSERT INTO test_cardinality_1
SELECT number, round(number / 100000), round(number / 1000)
FROM numbers(50000000)
b = 100 的数据有10w行:
SELECT count(1)
FROM test_cardinality_1
WHERE b = '100'
Query id: f26a7041-7051-428a-9b06-ee61df087bce
┌─count()─┐
│ 100001 │
└─────────┘
现在删除b=100的数据:
DELETE FROM test_cardinality_1 WHERE b = '100' settings allow_experimental_lightweight_delete = true
再次查询 b=100的数据,已经被删掉了:
SELECT count(1)
FROM test_cardinality_1
WHERE b = '100'
Query id: bad814eb-dcb3-4b23-8be7-a81968de03f8
┌─count()─┐
│ 0 │
└─────────┘
让我们来看看轻量级删除做了什么,打开 test_cardinality_1 表的目录,发现了熟悉的 mutation_49.txt 文件,说明轻量级删除也是一种异步的 mutation 操作:
# pwd
/chbase/data/data/data/default/test_cardinality_1
[root@ch9 test_cardinality_1]# cat ./mutation_49.txt
format version: 1
create time: 2022-12-14 15:44:16
commands: UPDATE _row_exists = 0 WHERE b = \'100\'
查询 mutations 系统表可以佐证:
SELECT
table,
mutation_id,
command,
is_done
FROM system.mutations
Query id: 7654fc0d-b578-46f6-ae19-becb0f6fd92b
┌─table──────────────┬─mutation_id─────┬─command────────────────────────────────┬─is_done─┐
│ test_cardinality_1 │ mutation_49.txt │ UPDATE _row_exists = 0 WHERE b = '100' │ 1 │
└────────────────────┴─────────────────┴────────────────────────────────────────┴─────────┘
它的 commands 是 UPDATE _row_exists = 0 WHERE b = \'100\' ,进入分区目录,发现发现多了一组 _row_exists 文件:
[root@ch9 all_1_28_2_49]# pwd
/chbase/data/data/store/a69/a69da83a-5760-49db-9b74-0b97aa06a394/all_1_28_2_49
[root@ch9 all_1_28_2_49]# ll
total 118248
-rw-r-----. 2 clickhouse clickhouse 117867360 Dec 14 15:40 a.bin
-rw-r-----. 2 clickhouse clickhouse 86040 Dec 14 15:40 a.mrk2
-rw-r-----. 2 clickhouse clickhouse 598571 Dec 14 15:40 b.bin
-rw-r-----. 2 clickhouse clickhouse 86040 Dec 14 15:40 b.mrk2
-rw-r-----. 2 clickhouse clickhouse 2033155 Dec 14 15:40 c.bin
-rw-r-----. 1 clickhouse clickhouse 409 Dec 14 15:44 checksums.txt
-rw-r-----. 2 clickhouse clickhouse 86040 Dec 14 15:40 c.mrk2
-rw-r-----. 1 clickhouse clickhouse 90 Dec 14 15:44 columns.txt
-rw-r-----. 2 clickhouse clickhouse 8 Dec 14 15:40 count.txt
-rw-r-----. 1 clickhouse clickhouse 10 Dec 14 15:44 default_compression_codec.txt
-rw-r-----. 2 clickhouse clickhouse 64057 Dec 14 15:40 primary.idx
-rw-r-----. 1 clickhouse clickhouse 132355 Dec 14 15:44 _row_exists.bin
-rw-r-----. 1 clickhouse clickhouse 86040 Dec 14 15:44 _row_exists.mrk2
这就是轻量级删除,"轻"之所在。
ALTER TABLE xxx DELETE 是把整个分区目录重写
DELETE FROM 是把删除的数据用掩码标记,在查询的时候过滤,在分区合并的时候删除
轻量级删除的设计思路相比之会好很多,因为它期望只涉及被删除部分的数据。
这个功能看起来不错,但是在ClickHouse毕竟不是OLTP数据库,目前轻量级删除有一些明确的问题和限制,例如:
1、轻量级删除也是延迟的,它也会导致一些分区的合并
2、对 wide 类型分区友好(一个列一个bin文件),compact类型要慎重(一组列一个bin文件),会导致磁盘的IOPS高,且增加Zookeeper的压力
3、在删除的过程中,涉及到的分区会变成 inactive 状态。如果删除涉及的分区很多,则大量旧分区的清理动作会变得很慢
4、轻量级删除会导致涉及到的分区名称都会变更(增加后缀 mutation_id),影响备份
本文分享自 ClickHouse的秘密基地 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!