前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解 StarRocks 的元数据管理

深入理解 StarRocks 的元数据管理

原创
作者头像
crossoverJie
发布2024-10-13 13:32:45
630
发布2024-10-13 13:32:45
举报
文章被收录于专栏:crossoverJie

背景

最近在排查 starrocks 线上的一个告警日志:

每隔一段时间都会打印 base-table 也就是物化视图的基表被删除了,但其实表还在,也没人去删除;我们就怀疑是否真的表被删除了(可能是 bug)。

与此同时还有物化视图 inactive 的日志,也怀疑如果视图是 inactive 之后会导致业务使用有问题。

为了确认这个日志是否对使用影响,就得需要搞清楚它出现的原因;于是我就着手从日志打印的地方开始排查。

问题排查

从这个代码可以看出,是在查询表的信息的时候没有查到,从而导致日志打印 base-table 被 dropped 了。

而我查询了几天的 drop table 的日志,依然没有找到可能是程序 bug 导致被删除的痕迹。

好在 starrocks 的日志打印非常详细,包含了线程名称、类+方法名称,还有具体的代码函数,很容易就定位日志输出的地方。

元数据

只是为何会调用到这里还需要阅读源码从而找到原因,在开始之前需要先了解一下 starrocks 元数据的一些基本概念。

其实在这篇文章:StarRocks 元数据管理及 FE 高可用机制中已经有全面的介绍,只是这篇文章有点早了,和现在最新的代码不太匹配。

在 StarRocks 元数据中会保存 Database、Table 等信息。

这些数据定期保存在 fe/meta 目录中。

StarRocks 对元数据的每一次操作(增删改查数据库、表、物化视图)都会生成 editLog 的操作日志。

image.png
image.png

新建数据库、修改表名称等

当 StarRocks 的 FE 集群部署时,会由 leader 的 FE 启动一个 checkpoint 线程,定时扫描当前的元数据是否需要生成一个 image.${JournalId} 的文件。

其实就是判断当前日志数量是否达到上限(默认是 5w)生成一次。

具体的流程如下:

  • 判断当前是否需要将日志生成 image
  • 加载当前 image 里的元数据到内存
  • 从 bdb 中读取最新的 Journal,然后进行重放(replay):其实就是更新刚才加载到内存中的元数据。
  • 基于内存中的元数据重新生成一份 image 文件
  • 删除历史的 image 文件
  • 将生成的 image 文件名称通知 FE 的 follower 节点,让他们下载到本地,从而可以实现 image 同步。

通知 follower 下载 image。

元数据同步流程

完整的流程图如下图:

在这个流程图有一个关键 loadImage 流程:

他会读取 image 这个文件里的数据,然后反序列化后加载到内存里,主要就是恢复数据库和表。

还会对每个表调用一次 onReload() 函数,而这个函数会只 MV(MATERIALIZED VIEWS) 生效。

这个函数正好就是在文初提到的这个函数 com.starrocks.catalog.MaterializedView#onReloadImpl

从他的实现来看就是判断视图所依赖的基表是否存在,如果有一个不存在就会将当前基表置为 inactive。

如果碰到视图的基表也是视图,那就递归再 reload 一次。

复现问题

既然知晓了这个加载流程,再结合源码应该不难看出这里的问题所在了。

从这里的加载数据库可以看出端倪,如果我的视图和基表不在同一个数据库里,此时先加载视图是不是就会出现问题?

加载视图的时候会判断基表是否存在,而此时基表所在的数据库还没加载到内存里,自然就会查询不到从而出现那个日志。

我之前一直在本地模拟,因为都是在同一个数据库里的基表和视图,所以一直不能复现。

只要将基表和视图分开在不同的数据库中,让视图先于数据库前加载就会触发这个日志。

修复问题

要修复这个问题也很简单,只要等到所有的数据库都表都加载完毕后再去 reload 物化视图就可以了。

当我回到 main 分支准备着手修改时,发现这个问题已经被修复了:

https://github.com/StarRocks/starrocks/pull/51002

修复过程也很简单,就是 reload 时跳过了 MV,等到所有的数据都加载完之后会在 com.starrocks.server.GlobalStateMgr#postLoadImage 手动加载 MV

这个 PR 修复的问题也是我一开始提到的,会打印许多令人误解的日志。

到这里就可以解释文章开头的那个问题了:打印的这个 base-table 被删除的日志对业务来说没有影响,只是一个 bug 导致出现了这个日志。

额外提一句,这个日志也比较迷,没有打印数据库名称,如果有数据库名称的话可能会更快定位到这个问题。

参考文章:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 问题排查
    • 元数据
      • 元数据同步流程
        • 复现问题
        • 修复问题
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档