OceanBase資料庫采用了基于 LSM Tree 結構作為資料庫的存儲引擎,資料被分為基線資料(SSTable)和增量資料(MemTable)兩部分,基線資料被儲存在磁盤中,當需要讀取的時候會被加載到資料庫的緩存中,當資料被不斷插入(或者修改時)在記憶體中緩存增量資料,當增量資料達到一定閥值時,就把增量資料重新整理到磁盤上,當磁盤上的增量資料達到一定閥值時再把磁盤上的增量資料和基線資料進行合并。

對于 LSM Tree 結構,如果儲存多個層次的 MemTable 的話,會帶來很大的空間存儲問題,OceanBase 對 LSM Tree 結構進行了簡化,隻保留了C0層和C1層(參考上期有問必答内容),也就是說,記憶體中的增量資料會被以MemTable的方式儲存在磁盤中,這個過程被稱之為轉儲(compaction),當轉儲了一定的次數之後,就需要把磁盤上的MemTable與基線資料進行合并(merge)。以下是轉儲與合并的詳細解釋:
轉儲:由于記憶體中對資料的修改會持續發生,是以在記憶體中的 MemTable 就會越來越多,為了釋放記憶體空間,OceanBase 會定義一個 MemTable 占用記憶體比例的閥值,當到達這個閥值的時候,就要把一些最舊的 MemTable 中的資訊進行歸并排序,并儲存到磁盤上,形成C0級别的資料,這個過程稱之為轉儲,OceanBase 把這個過程稱之為轉儲(Minor Freeze)。
合并:合并操作(Major Freeze)是将動靜态資料做歸并,也就是産生新的C1層的資料,會比較費時。當轉儲産生的增量資料積累到一定程度時通過 Major Freeze 實作大版本的合并。由于在合并的過程中為了保證資料的一緻性,就需要在合并的過程中暫停正在被合并的資料上的事務,這對性能來說是會有影響的,OceanBase 對合并操作進行了細化,分為增量合并,輪轉合并和全量合并。
下面的表格描述了轉儲與合并的差別:
OceanBase同時也結合了傳統的關系型資料庫的特點,也存在資料庫塊的概念。在 OceanBase 中,資料檔案配置設定空間的機關稱為宏塊(marco block),如果大家對Oracle比較熟悉的話,可以簡單的認為宏塊對應了Oracle中的extent;每個宏塊又分成了若幹個16k大小的微塊,它是每次資料庫IO的最小機關(相當于傳統資料庫的塊),資料庫中的各種資料就儲存在微塊當中。由于宏塊的大小是2M,而且 OceanBase 采用了LSM Tree 結構來儲存資料,資料是按照表的主鍵排序的。是以,OceanBase 的宏塊是可以分裂的,而如果資料被删除了,相鄰的宏塊也可以進行合并
由于 SSTable 中的資料是基線資料,絕大部分情況下,這部分資料是靜态的,是以 OceanBase 預設會對這些資料在進行合并時進行分析,并根據各個列的資料分布情況對資料進行編碼,目前支援的編碼方式有:字典編碼、RLE編碼、常量編碼、內插補點編碼、字首編碼、列間編碼等。在對資料進行編碼之後,再通過通用的壓縮算法對資料進行壓縮,就可以實作很好的資料壓縮比,同時對于讀取性能基本沒有影響,而且使合并時的寫入性能更好。下面的圖檔展示了使用字典方式對列rate_id進行編碼的基本過程。