OceanBase子表分裂與合併

凌洛發表於2018-03-30

子表分裂由ChunkServer在定期合併過程中執行,由於每個子表包含多個副本,且分佈在多臺ChunkServer上,如何確保多個副本之間的分裂點保持一致成為問題的關鍵。OcanBase採用了一種比較直接的做法:每臺ChunkServer使用相同的分裂規則。

由於每個子表的不同副本之間的基線資料完全一致,且定期合併過程中凍結的增量資料也完全相同,只要分裂規則一致,分裂後的子表主鍵範圍也保證相同。

OcanBase曾經有一個線上版本的分裂規則如下:只要定期合併過程中產生的資料量超過256MB,就生成一個新的子表。假設定期合併產生的資料量為257MB,那麼最後將分裂為兩個子表,其中,前一個子表(記為r1)的資料量為256MB,後一個子表(記為r2)的資料量為1MB。接著,r1接受新的修改,資料量很快又超過256MB,於是,又分裂為兩個子表。系統執行一段時間後,充斥著大量資料量很少的子表。

為了解決分裂產生小子表的問題,需要確保分裂以後的每個子表資料量大致相同。OceanBase對每個子表記錄了兩個後設資料:資料行數row_count以及子表大小(occupy_size)。根據這兩個值,可以計算出每行資料的平均大小,即:occupy_size/row count。

根據資料行平均大小,可以計算出分裂後的子錶行數,從而得到分裂點。子表合併相對更加麻煩,步驟如下:
1)合併準備:RootServer選擇若干個主鍵範圍連續的小子表;
2)子表遷移:將待合併的若干個小子表遷移到相同的ChunkServer機器;
3)子表合併:往ChunkServer機器傳送子表合併命令,生成合並後的子表範圍。

【例】某OceanBase叢集中有3臺ChunkServer:ChunkServerl(包含子表A1、A3),ChunkServer2(包含子表A2、A3),ChunkServer3(包含子表A1、A2),其中,Al和A2分別為10MB,A3為256MB。RootServer 掃描RootTable後發現Al和A2滿足子表合併條件,首先發起子表遷移,假設將Al遷移到ChunkServer2。使得Al和A2在相同的ChunkServer上,接著分別向ChunkServer2和ChunkServer3發起子表合併命令。

子表合併完成以後,子表分佈情況為:ChunkServerl(包含子表A3),
ChunkServer2(包含子表A4(A1,A2).A3),ChunkServer3(包含子表A4(A1,A2)),其中,A4是子表Al和A2合併後的結果。
每個子表包含多個副本,只要某一個副本合併成功,OceanBase就認為子表合併成功,其他合併失敗的子表將通過垃圾回收機制刪除掉。


相關文章