初学者记一次被clichouse TTL坑经历

随着clickhouse越来越火,近日也部署一个clickhouse集群,测试体验使用一下,满满的热情却被TTL操作给打脸,下面是测试用例

#创建测试表
CREATE TABLE test_tb (
  id UInt16,
  create_time Date,
  comment Nullable(String)
) ENGINE = MergeTree()
   PARTITION BY create_time
     ORDER BY  (id, create_time)
     PRIMARY KEY (id, create_time)
     TTL create_time + INTERVAL 1 MONTH
     SETTINGS index_granularity=8192;
#写入数据
insert into test_tbl values(0, '2019-12-12', null);
insert into test_tbl values(0, '2019-12-12', null);
insert into test_tbl values(1, '2019-12-13', null);
insert into test_tbl values(1, '2019-12-13', null);
insert into test_tbl values(2, '2019-12-14', null);
#查询数据: 可以看到虽然主键id、create_time相同的数据只有3条数据,但是结果却有5行。
select count(*) from test_tbl;
┌─count()─┐
│       5 │
└─────────┘
由于MergeTree采用类似LSM tree的结构,很多存储层处理逻辑直到Compaction期间才会发生。因此强制后台compaction执行完毕,再次查询,发现仍旧没有一条数据。
optimize table test_tbl final;
select count(*) from test_tbl;
┌─count()─┐
│       0 │
└─────────┘

卧槽,这是啥情况???数据丢失,难道clickhouse数据库bug?
邮件咨询了战斗民族等回复中…,自己动手丰衣足食 先一步一步的排查原因,从最开始的建表开始下手逐次删减添加的子句的定义选项PARTITION BY 、ORDER BY、PRIMARY KEY,排查了二十分钟发现是TTL 生效的原因,什么是TTL操作呢?TTL可以设置值的生命周期,它既可以为整张表设置,也可以为每个列字段单独设置。如果TTL同时作用于表和字段,ClickHouse会使用先到期的那个。
列字段 TTL
当列字段中的值过期时, ClickHouse会将它们替换成数据类型的默认值。如果分区内,某一列的所有值均已过期,则ClickHouse会从文件系统中删除这个分区目录下的列文件。
表 TTL
当表内的数据过期时, ClickHouse会删除所有对应的行。
官网介绍地址,请参见

https://clickhouse.tech/docs/zh/operations/table_engines/mergetree/#table_engine-mergetree-ttl

而我的建表语句里刚好有TTL操作: TTL create_time + INTERVAL 1 MONTH(表数据的生命周期为期一个月 )它的含义是当ClickHouse合并数据分区时, 会根据create_time这一列的时间数据以及之后一个月的这样一周期内的数据进行保存,不在这一时间段内的数据,ck就是主动删除分区目录下的列文件。如我遇见的这样,插入字段的时间是2019年12月的时间,到2020年1月份数据是有效的超过了TTL的周期的数据就是被删除,现在是2020年2月份,因此才会导致数据丢失这一事件。这样一段小插曲让我了解了什么是数据库TTL操作,同时也加深了对ck用法的理解

数仓建设需要考虑数据的生命周期问题,数据的生命周期包括数据最初的写入,存储,处理,查询,归档和销毁几个基本的阶段。现实生活中数仓数据量的成倍增长,不但产生了巨大容量的存储,同时也造成管理的困难,更换存储方式和存储迁移对项目来讲都是需要考虑成本和风险的。clickhouse这样的一个设计,可以有效处理解决数据有效的存储周期和销毁的问题。ck的出现对数据存储的数仓的业务选型又添加一种选择。

你可能感兴趣的:(初学者记一次被clichouse TTL坑经历)