深入理解 StarRocks 的元數據管理
背景
最近在排查 starrocks 線上的一個告警日志:
圖片
每隔一段時間都會打印 base-table 也就是物化視圖的基表被刪除了,但其實表還在,也沒人去刪除;我們就懷疑是否真的表被刪除了(可能是 bug)。
與此同時還有物化視圖 inactive 的日志,也懷疑如果視圖是 inactive 之后會導致業務使用有問題。
為了確認這個日志是否對使用影響,就得需要搞清楚它出現的原因;于是我就著手從日志打印的地方開始排查。
問題排查
圖片
從這個代碼可以看出,是在查詢表的信息的時候沒有查到,從而導致日志打印 base-table 被 dropped 了。
而我查詢了幾天的 drop table 的日志,依然沒有找到可能是程序 bug 導致被刪除的痕跡。
好在 starrocks 的日志打印非常詳細,包含了線程名稱、類+方法名稱,還有具體的代碼函數,很容易就定位日志輸出的地方。
元數據
只是為何會調用到這里還需要閱讀源碼從而找到原因,在開始之前需要先了解一下 starrocks 元數據的一些基本概念。
其實在這篇文章:StarRocks 元數據管理及 FE 高可用機制中已經有全面的介紹,只是這篇文章有點早了,和現在最新的代碼不太匹配。
在 StarRocks 元數據中會保存 Database、Table 等信息。
這些數據定期保存在 fe/meta 目錄中。
圖片
StarRocks 對元數據的每一次操作(增刪改查數據庫、表、物化視圖)都會生成 editLog 的操作日志。
圖片
新建數據庫、修改表名稱等。
當 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 導致出現了這個日志。
額外提一句,這個日志也比較迷,沒有打印數據庫名稱,如果有數據庫名稱的話可能會更快定位到這個問題。
參考文章:
- https://xie.infoq.cn/article/6f2f9f56916f0eb2fdb6b001a
- https://github.com/StarRocks/starrocks/pull/51002