【V1与V2简介】
Iceberg在V1的格式中定义了,如何使用不可变类型的文件(Parquet、ORC、AVRO)来管理大型分析型的表,包括元数据文件、属性、数据类型、表的模式,分区信息,以及如何写入与读取。
而在V2的格式中,在V1的基础上增加了如何通过这些类型的表实现行级别的更新与删除功能。其最主要的改变是引入了delete file记录需要删除的行数据,这样可以在不重写原有(数据)文件的前提下,实现行数据的更新与删除。
【行级别删除的原理】
1. DeleteFile的表示
在V1版本中,只有DataFile的概念,即记录添加到iceberg中的行数据集。而DeleteFile(删除文件)则记录的是被删除的行的数据集。
删除行数据的方式分为两种:Equality Deletes和Position Deletes。
所谓Equality Deletes就是等值删除,指定一个或多个列的值,其中包含该列值的每一行数据都被视为已删除。例如删除id=10的数据;而Position Deletes为位置删除,删除指定文件中指定位置的行数据。
在V2版本在清单列表文件中(snap-xxx.avro)中增加了一个字段content,以标识哪些文件是DataFile,哪些是DeleteFile。content的值,0表示数据文件、1表示删除数据文件。
对于这两种删除方式,在清单文件(xxx.avro)中,同样通过content字段来表示:0表示新增的文件、1表示Position deletes、2表示Equality deletes。
1)等值删除
在清单文件中,增加equality_ids字段标记进行等值比较的字段的ID集合。
同时,DeleteFile文件记录的内容,则是在删除时,自定义的schema,且至少包含进行等值比较的字段列的值。
2)位置删除
在DeleteData文件中固定列字段为file_path和pos,以及可选的row字段。其中file_path指定需要待删除的行数据所在的数据文件位置,而pos则指定待删除的行记录的起始位置
2. Sequence Nubmer(序号)
为实现行级别的删除而引入了删除文件,那么在数据读取时需要有方式来判断执行的先后顺序,比如对同一条记录,新增、删除、再新增,其先后顺序会直接导致数据的正确性。因此,引入了Sequence Number(序号)来标识数据的执行先后顺序。
序号随快照的产生而生成,并写入快照的元数据文件中(snap-xxx.avro);同时,本次快照所产生的清单文件(xx.avro)会直接继承(使用)快照对应的序号。而本次快照新创建的数据文件和删除文件,序号表示并记录在清单文件中(实际读取到内存后,会被替换为清单文件的序号), 而如果是以"exist"的方式出现在清单文件中(清单文件中status的值为0),则为以产生该文件的快照的序号写入到清单文件中。
【总结】
本文主要从文件格式上讲述了iceberg版本2中如何实现行级别的删除,具体为deletefile的表示。实际上,在读写的逻辑处理上还会有较多的约束和注意点,我们后面的文章再来重点讲述读写流程。