整个链路终于要连通啦~
这次从fe出发,看一下从发送 create materialized view开始,发生了什么。
首先是fe监听到sql,入口为:ConnectProcessor.java :: processOnce (处理一次sql请求),然后根据不同的sql类型,分发到不同的handle去处理。创建物化视图属于ddl操作,分发到 DdlExecutor 去执行,根据stmt判断Ddl类型为创建物化视图,然后转到alter.MaterializedViewHandler::processCreateMaterializedView()处理。
创建物化视图分为两个步骤,检查stmt是否合规,创建物化视图job。
stmt校验主要是从下面几个方面:物化视图base表名称、base表状态是否正常、物化视图列是否有效。
Rollup job创建流程:
1、遍历base 表 partition。(此处数据类型为 HasMap)
2、遍历 partition下的tablet,创建物化视图下的tablet,将Rollup任务加入列表。map<long ,map<long ,long >> // 依次为partitionId、rollupTabletId、baseTabletId 如果有多个备份的话,则创建新的备份。
3、可以看到 MaterializedViewHandler 继承了 Daemon,在Daemon中每间隔一个周期,就执行一次 runAfterCatalogReady() ,然后在MaterializedViewHandler中执行 runAlterJobV2()
4、根据配置:max_running_rollup_job_num_per_table 判断是否立即执行当前job,否则一直等待之前的job执行完成。job 初始状态为 pending。
5、pending job 依次遍历partition、tablet、replica,然后向be发送创建tablet请求,等待创建tablet成功之后将job 状态置为 waiting txn
6、waiting txn job 也是同样依次遍历 partition、tablet、replica ,然后向be发送创建rollup请求,然后执行历史数据的转换,将job设置为running。
7、running job的逻辑比较简单,就是等待be执行成功,然后检查副本执行情况,最终job 完成。
所以问题排查到这里就结束了。因为遍历base表的时候,是HashMap,而且提交 task时也是HashMap,众所周知,HashMap key的遍历是随机的,所以哪一个分区先被提交到be是不确定的,所以就造成了之前的问题,当日实时写入的数据,在进行创建物化视图的过程中,一直得不到
compaction。
ye!