StarRocks 的元数据管理如何才能达到深入理解?
- 内容介绍
- 文章标签
- 相关推荐
我们先从一个让人头大的日志说起。你有没有在排查线上问题的时候,看到一堆莫名其妙的日志,然后怀疑人生?

换句话说... 比如 最近我在排查 StarRocks 线上一个告警日志时就遇到了一个特别“亲切”的场景:每隔一段时间,日志里就会蹦出一条“base-table 被删除了”的提示。但其实表根本没被删,也没人动过这让人怎么想都觉得是程序的锅。于是我决定深入源码,看看这到底是啥情况。
害... 我们先来回顾一下问题的来龙去脉。这个问题的起因,其实是一个隐藏的 bug,导致了日志打印出“基表被删除”的信息,但其实表还在。这其实不是用户操作导致的,而是一个在加载过程中,视图的基表还没加载到内存,就被查询了导致了误报。
元数据管理的“坑”
StarRocks 的元数据管理,其实是一个非常复杂的系统。它不像你想象的那样简单,比如“数据库被删了”这种日志,可能只是个假象。我们来看一下它到底怎么工作的,一言难尽。。
StarRocks 的元数据管理机制,主要依赖于 editLog 和 image 两个核心机制。每一次操作都会生成 editLog,然后定期生成 image 文件,用于快速恢复元数据。
这些 editLog 会记录在 fe/meta 目录中, 而 image 文件则会定期生成, 说白了就是... 用于快速恢复数据库状态。这个机制听起来很美好,但实际操作中,问题就来了。
比如 我们遇到的这个“base-table 被删除”的日志,其实是主要原因是在加载物化视图时基表还没加载到内存,导致查询不到基表,于是就报错了。这其实不是数据真的被删了而是加载顺序的问题,这是可以说的吗?。
深入源码:问题出在哪?
我们来看一下这个流程图:
在 StarRocks 的加载流程中, loadImage 会读取 image 文件,然后反序列化后加载到内存中。 我给跪了。 这个过程主要是恢复数据库和表。但问题就出在如果视图和基表不在同一个数据库里加载顺序就可能出问题。
正宗。 比如 如果视图所在的数据库还没加载到内存,就去加载物化视图,那就会出现“基表被删除”的日志。这其实是个 bug,主要原因是视图的基表还没加载到内存,自然就查不到,于是就报错了。
要修复这个问题也很简单, 只要等到所有的数据库和表都加载完毕后再去加载物化视图,就不会出现这个问题了,往白了说...。
修复过程
也许吧... 修复过程也很简单, 就是 reload 时跳过了 MV等到所有的数据都加载完之后会在 #postLoadImage 手动加载 MV。这个流程图如下图:
还会对每个表调用一次 onReload 函数,而这个函数只对物化视图生效。 交学费了。 如果碰到视图的基表也是视图,那就递归再 reload 一次。
这个修复方案其实很简单,就是等所有数据库和表都加载完之后再加载物化视图。 格局小了。 这样就不会出现“基表被删除”的问题了。
相关产品对比
| 产品 | 元数据管理机制 | 是否支持物化视图 | 是否支持自动恢复 |
|---|---|---|---|
| StarRocks | editLog + image | 是 | 是 |
| ClickHouse | ZooKeeper + ReplicatedMergeTree | 否 | 是 |
| Doris | editLog + image | 是 | 是 |
从这个表格可以看出,StarRocks 的元数据管理机制其实是很先进的。它通过 editLog 和 image 机制,实现了元数据的高可用和快速恢复。但这个机制也不是没有问题的,比如我们遇到的这个 bug,就是加载顺序的问题。
修复方案
何不... 要修复这个问题也很简单,只要等到所有的数据库都表都加载完毕后再去 reload 物化视图就可以了。这个修复方案其实很简单,就是等所有数据都加载完之后再去加载物化视图,就不会出现这个问题了。
这个 PR 修复的问题也是我一开始提到的,会打印许多令人误解的日志。其实在这篇文章:StarRocks 元数据管理及 FE 高可用机制中已经有全面的介绍, 复盘一下。 只是这篇文章有点早了和现在最新的代码不太匹配。
这篇文章主要是为了搞清楚“base-table 被删除”这个日志的来龙去脉。通过深入源码,我们发现,其实这个问题不是数据真的被删了而是加载顺序的问题。只要将基表和视图分开在不同的数据库中,让视图先于数据库前加载就会触发这个日志,我坚信...。
要修复这个问题也很简单,只要等到所有的数据库都表都加载完毕后再去 reload 物化视图就可以了。修复过程也很简单, 就是 reload 时跳过了 MV等到所有的数据都加载完之后会在 #postLoadImage 手动加载 MV。这个流程图如下图:
要修复这个问题也很简单,只要等到所有的数据库都表都加载完毕后再去 reload 物化视图就可以了,这是可以说的吗?。
从这个代码可以看出, 是在查询表的信息的时候没有查到,从而导致日志打印 base-table 被 dropped 了。要修复这个问题也很简单, 就是 reload 时跳过了 MV等到所有的数据都加载完之后会在 #postLoadImage 手动加载 MV。这个流程图如下图:
我们先从一个让人头大的日志说起。你有没有在排查线上问题的时候,看到一堆莫名其妙的日志,然后怀疑人生?

换句话说... 比如 最近我在排查 StarRocks 线上一个告警日志时就遇到了一个特别“亲切”的场景:每隔一段时间,日志里就会蹦出一条“base-table 被删除了”的提示。但其实表根本没被删,也没人动过这让人怎么想都觉得是程序的锅。于是我决定深入源码,看看这到底是啥情况。
害... 我们先来回顾一下问题的来龙去脉。这个问题的起因,其实是一个隐藏的 bug,导致了日志打印出“基表被删除”的信息,但其实表还在。这其实不是用户操作导致的,而是一个在加载过程中,视图的基表还没加载到内存,就被查询了导致了误报。
元数据管理的“坑”
StarRocks 的元数据管理,其实是一个非常复杂的系统。它不像你想象的那样简单,比如“数据库被删了”这种日志,可能只是个假象。我们来看一下它到底怎么工作的,一言难尽。。
StarRocks 的元数据管理机制,主要依赖于 editLog 和 image 两个核心机制。每一次操作都会生成 editLog,然后定期生成 image 文件,用于快速恢复元数据。
这些 editLog 会记录在 fe/meta 目录中, 而 image 文件则会定期生成, 说白了就是... 用于快速恢复数据库状态。这个机制听起来很美好,但实际操作中,问题就来了。
比如 我们遇到的这个“base-table 被删除”的日志,其实是主要原因是在加载物化视图时基表还没加载到内存,导致查询不到基表,于是就报错了。这其实不是数据真的被删了而是加载顺序的问题,这是可以说的吗?。
深入源码:问题出在哪?
我们来看一下这个流程图:
在 StarRocks 的加载流程中, loadImage 会读取 image 文件,然后反序列化后加载到内存中。 我给跪了。 这个过程主要是恢复数据库和表。但问题就出在如果视图和基表不在同一个数据库里加载顺序就可能出问题。
正宗。 比如 如果视图所在的数据库还没加载到内存,就去加载物化视图,那就会出现“基表被删除”的日志。这其实是个 bug,主要原因是视图的基表还没加载到内存,自然就查不到,于是就报错了。
要修复这个问题也很简单, 只要等到所有的数据库和表都加载完毕后再去加载物化视图,就不会出现这个问题了,往白了说...。
修复过程
也许吧... 修复过程也很简单, 就是 reload 时跳过了 MV等到所有的数据都加载完之后会在 #postLoadImage 手动加载 MV。这个流程图如下图:
还会对每个表调用一次 onReload 函数,而这个函数只对物化视图生效。 交学费了。 如果碰到视图的基表也是视图,那就递归再 reload 一次。
这个修复方案其实很简单,就是等所有数据库和表都加载完之后再加载物化视图。 格局小了。 这样就不会出现“基表被删除”的问题了。
相关产品对比
| 产品 | 元数据管理机制 | 是否支持物化视图 | 是否支持自动恢复 |
|---|---|---|---|
| StarRocks | editLog + image | 是 | 是 |
| ClickHouse | ZooKeeper + ReplicatedMergeTree | 否 | 是 |
| Doris | editLog + image | 是 | 是 |
从这个表格可以看出,StarRocks 的元数据管理机制其实是很先进的。它通过 editLog 和 image 机制,实现了元数据的高可用和快速恢复。但这个机制也不是没有问题的,比如我们遇到的这个 bug,就是加载顺序的问题。
修复方案
何不... 要修复这个问题也很简单,只要等到所有的数据库都表都加载完毕后再去 reload 物化视图就可以了。这个修复方案其实很简单,就是等所有数据都加载完之后再去加载物化视图,就不会出现这个问题了。
这个 PR 修复的问题也是我一开始提到的,会打印许多令人误解的日志。其实在这篇文章:StarRocks 元数据管理及 FE 高可用机制中已经有全面的介绍, 复盘一下。 只是这篇文章有点早了和现在最新的代码不太匹配。
这篇文章主要是为了搞清楚“base-table 被删除”这个日志的来龙去脉。通过深入源码,我们发现,其实这个问题不是数据真的被删了而是加载顺序的问题。只要将基表和视图分开在不同的数据库中,让视图先于数据库前加载就会触发这个日志,我坚信...。
要修复这个问题也很简单,只要等到所有的数据库都表都加载完毕后再去 reload 物化视图就可以了。修复过程也很简单, 就是 reload 时跳过了 MV等到所有的数据都加载完之后会在 #postLoadImage 手动加载 MV。这个流程图如下图:
要修复这个问题也很简单,只要等到所有的数据库都表都加载完毕后再去 reload 物化视图就可以了,这是可以说的吗?。
从这个代码可以看出, 是在查询表的信息的时候没有查到,从而导致日志打印 base-table 被 dropped 了。要修复这个问题也很简单, 就是 reload 时跳过了 MV等到所有的数据都加载完之后会在 #postLoadImage 手动加载 MV。这个流程图如下图:

