天天看點

OceanBase 子表分裂與合并

子表分裂由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就認為子表合并成功,其他合并失敗的子表将通過垃圾回收機制删除掉。

繼續閱讀