该文章以SnapshotProducer和HadoopTableOperations解析Iceberg中commit的流程,如有不足及错误之处,欢迎大家指正交流。
首先,调用apply()获取最新的snapshot信息
- refresh()刷新tableMetadata
- 获取当前snapshotId和下一个sequenceNumber
- validate(TableMetadata currentMetadata)校验操作是否有效
- apply(TableMetadata metadataToUpdate)更新到tableMetadata并返回新的manifest列表
- 针对v2表或启用write.manifest-lists.enabled(默认为true,大部分都会写manifest-lists文件,即snap-xxx文件)
- manifestListPath()新建manifest-lists文件
- 构建ManifestListWriter
- 通过异步线程池遍历并缓存新的manifest列表
- 通过ManifestListWriter将manifest信息写入manifestList
随后,调用TableMetadata.buildFrom(base)构建update新的tableMetadata。并根据当前snapshot是否已存在于tableMetadata和是否支持WAP(write-audit-publish)工作流填充TableMetadata信息。构建新的tableMetadata,若元数据没有修改,则不需要commit
- 若当前shapshot已存在于tableMetadata,则将新的snapshot置为main_branch的snapshot
- 若不满足1且支持WAP工作流,将新的snapshot添加到新的tableMetadata中
- 如果都不满足,则将新的snapshot添加到新的tableMetadata中,并将新的snapshot置为main_branch的snapshot
最后,调用TableOperations#commit(TableMetadata base, TableMetadata metadata)进行提交(以HadoopTableOperations为例)
- versionAndMetadata()获取当前的version和tableMetadata
- 检查当前的tableMetadata与基准的tableMetadata相同,并新的tableMetadata与基准的tableMetadata相比有更新
- 生成metadata临时目标文件路径,并将新的metadata内容写入该文件
- 获取下一个version号,并生成最终metadata file
- 将临时目标文件重命名为最终metadata文件
- 将version信息写入VersionHint文件
- 删除旧的metadata文件(将之前的metadata文件保存起来,在commit时检查下次不需要保留的进行移除)
当确认commit成功之后,清理未commited的与未使用的manifest文件,并发送消息通知监听者。