继上次Commit的解析之后,今天再来看一下Iceberg是如何产生Commit所需的Snapshot(manifest-list)的信息,以及其中的一些处理。今天以MergingSnapshotProducer中的apply方法为例进行解析。
首先,获取当前的Snapshot信息,对DataFile相关的Manifest进行过滤获取当前DataFile相关的Manifest列表。并获取本次Snapshot中有效DataFile的最小SequenceNumber(取DataFile相关的有效Manifest中的最小值与当前Snapshot的SequenceNumber中的最小值),用于后续过滤并自动删除小于该SequenceNumber的DeleteFile。
下面详细说明一下如何过滤Manifest(该过程中会比较DeleteManifest的SequenceNumber进行DeleteFile的自动删除):
- 若缓存中已存在对应manifest,则直接返回
- 若Manifest中全是DELETED的文件或者Manifest中不包含本次DELETED的文件,则认为该Manifest有效并返回
- 根据注释可以了解,确定Manifest中是否真的有DeletedFiles,如果没有,则认为该Manifest有效并返回
- 若Manifest中有DeletedFiles,则重写Manifest。重写规则为:若文件信息本身就是DELETED,则丢弃该文件信息;若文件信息在本次Snapshot中删除,则将文件信息置为DELETED;剩余的文件信息均置为EXISTING(具体可进filterManifestWithDeletedFiles自行阅读)
至此,我们获取到历史中有在本次Snapshot中需要DELETED的有效Manifest且均已更新。随后新建本次Snapshot新添加文件信息相关的Manifest,并更新Snapshot的统计信息。最后根据commit.manifest-merge.enabled配置确定是否合并Manifest(默认为true)。
下面详细解析一下如何合并Manifest:
- 首先根据partitionSpecId对Manifest进行分组
- 将同组的Manifest根据逆序进行分包合并
- 最后按包合并,合并过程将本次Snapshot产生的DELETED标记为DELETED,非本次的则丢弃,将本次Snapshot产生的ADDED标记为ADDED,其余都置为EXISTING(具体可进createManifest自行阅读)