OceanBaseデータベースのストレージエンジンはLSM-Treeアーキテクチャに基づいており、データを静的ベースラインデータ(SSTableに格納)と動的増分データ(MemTableに格納)の2つに分けています。SSTableは読み取り専用で、一度生成されると変更されず、ディスクに保存されます。MemTableは読み書き可能で、メモリに保存されます。データベースのDML操作(挿入、更新、削除など)はまずMemTableに書き込まれ、MemTableが一定のサイズに達すると、ディスクにフラッシュしてSSTableとなります。クエリ実行時には、SSTableとMemTableに対して別々にクエリを実行し、その結果をマージしてSQL層に返します。同時に、メモリ上ではBlock CacheとRow cacheを実装しており、ベースラインデータへのランダムな読み取りを回避します。
メモリ内の増分データが一定の規模に達すると、増分データとベースラインデータのメジャーコンパクションがトリガーされ、増分データがディスクにフラッシュされます。また、毎晩のアイドルタイムには、システムが自動的に日次メジャーコンパクションも実行します。
OceanBaseデータベースは本質的にベースライン + 増分のストレージエンジンであり、LSM-Treeアーキテクチャの利点を維持しつつ、従来のリレーショナルデータベースストレージエンジンの長所も取り入れています。
従来のデータベースはデータを多数のページに分割しますが、OceanBaseデータベースも従来のデータベースの考え方を参考に、データファイルを2MBを基本単位にマクロブロックに分割し、各マクロブロック内部をさらに複数の可変長のマイクロブロックに細分化しています。メジャーコンパクション時にはマクロブロック単位でデータの再利用が行われ、更新されていないデータのマクロブロックは再度開いて読み取ることがないため、メジャーコンパクション期間中のライトアンプリフィケーションを可能な限り抑えることができ、従来のLSM-Treeアーキテクチャのデータベースと比較してメジャーコンパクションコストを大幅に削減しています。
OceanBaseデータベースはベースライン + 増分の設計を採用しているため、データの一部はベースラインに、一部は増分に存在します。原理上、毎回のクエリではベースラインと増分の両方を読む必要があります。このため、OceanBaseデータベースでは特に単一行に対する最適化を含め、多くの最適化が施されています。OceanBaseデータベース内部では、データブロックだけでなく行もキャッシュされ、行キャッシュは単一行に対するクエリ性能を大幅に向上させます。行が存在しない「NULLクエリ」に対しては、ブルームフィルターを構築し、そのブルームフィルターをキャッシュします。OLTP業務の大部分は小規模なクエリであり、小規模クエリの最適化により、OceanBaseデータベースは従来のデータベースのようにデータブロック全体を解析するオーバーヘッドを回避し、メモリデータベースに近い性能を実現しています。また、ベースラインは読み取り専用データであり、内部では連続ストレージ方式を採用しているため、OceanBaseデータベースは比較的過激な圧縮アルゴリズムを使用でき、高い圧縮率を実現しつつクエリ性能に影響を与えず、コストを大幅に削減しています。
古典的なデータベースの長所を取り入れた上で、OceanBaseデータベースはより汎用的なLSM-Treeアーキテクチャのリレーショナルデータベースストレージエンジンを提供し、以下の特徴を備えています:
低コスト:LSM-Treeの書き込みデータは更新されない特性を活用し、独自の行列混合エンコーディングと汎用圧縮アルゴリズムを組み合わせることで、OceanBaseデータベースのデータストレージ圧縮率は従来のデータベースに比べて10倍以上向上しています。
やさしさ:他のLSM-Treeデータベースとは異なり、OceanBaseデータベースはアクティブトランザクションのディスクフラッシュをサポートすることで、ユーザーの大規模トランザクション/長時間トランザクションの正常な実行やロールバックを保証し、多段階のメジャーコンパクションとフラッシュメカニズムにより、パフォーマンスとスペースの最適なバランスを実現します。
高性能:一般的なポイントクエリに対しては、OceanBaseデータベースは多段階キャッシュの高速化を提供し、極めて低い応答遅延を保証します。範囲スキャンに対しては、ストレージエンジンがデータエンコーディングの特性を活用してクエリフィルター条件の計算を下押しし、ネイティブなベクトル化サポートを提供します。
高信頼性:全リンクのデータ検証に加え、ネイティブ分散型の利点を活用し、OceanBaseデータベースはグローバルメジャーコンパクション時にマルチレプリカ比較および主表とインデックス表の比較検証を行い、ユーザーデータの正確性を保証します。同時に、バックグラウンドスレッドによる定期的なスキャンを実施し、サイレントエラーを回避します。
ストレージエンジンの機能
機能モジュールの観点から、OceanBaseデータベースのストレージエンジンは大まかに以下の部分に分けられます。
データストレージ
データの組織
他のLSM-Treeデータベースと同様に、OceanBaseデータベースもデータをメモリ内の増分データ(MemTable)とディスク上の静的データ(SSTable)の2つの階層に分けています。SSTableは読み取り専用で、一度生成されると変更されず、ディスクに保存されます。MemTableは読み書き可能で、メモリに保存されます。データベースのDML操作(挿入、更新、削除など)はまずMemTableに書き込まれ、MemTableが一定のサイズに達すると、ディスクにフラッシュしてSSTableとなります。
さらに、OceanBaseデータベースでは、SSTableはMini SSTable、Minor SSTable、Major SSTableの3種類に細分化されます。MemTableはMini Compactionによりデータをディスク上のMini SSTableに転送し、複数のMini SSTableが一定のしきい値に達すると、Minor CompactionがトリガーされてMini SSTableまたはMinor SSTableとなります。そして、OceanBaseデータベース特有の日次メジャーコンパクションが開始されると、各パーティションの元のベースラインSSTable(Major SSTable)とすべてのMini SSTableおよびMinor SSTableが統合され、新しいMajor SSTableとなります。
ストレージ構造
OceanBaseデータベースでは、各パーティションの基本ストレージ単位は個々のSSTableであり、すべてのストレージの基本粒度はマクロブロックです。データベース起動時、データファイル全体を2MBの固定長でマクロブロックに分割し、各SSTableは実質的に複数のマクロブロックの集合です。
各マクロブロック内部はさらに複数のマイクロブロックに細分化されます。マイクロブロックの概念は従来のデータベースのページ/ブロックの概念と似ていますが、LSM-Treeの特性を活用したOceanBaseデータベースのマイクロブロックは圧縮により可変長となっています。マイクロブロックの圧縮前サイズは、テーブル作成時に
block_sizeを指定することで決定できます。マイクロブロックは、ユーザーが指定するストレージ形式に応じて、encoding形式またはflat形式で保存されます。encoding形式のマイクロブロックでは、内部データが行と列の混合モードで保存されます。一方、flat形式のマイクロブロックでは、すべてのデータ行が平铺されて保存されます。
圧縮エンコード
OceanBaseデータベースは、マイクロブロック内のデータを、ユーザーテーブルが指定したパターンに従ってエンコードおよび圧縮します。ユーザーテーブルでencodingが有効な場合、各マイクロブロック内のデータは列単位で別々にエンコードされます。エンコードルールには、辞書/ラン/定数/差分などが含まれます。各列の圧縮が終了した後、さらに複数の列に対して、列間の等値/サブストリングなどのルールでエンコードが行われます。このエンコードにより、データの大幅な圧縮が可能になるだけでなく、抽出された列内特徴情報により、その後のクエリ速度もさらに向上します。
エンコード圧縮後、OceanBaseデータベースは、ユーザーが指定した汎用圧縮アルゴリズムを使用してマイクロブロックデータを無損失圧縮することもサポートしており、データ圧縮率をさらに向上させることができます。
ダンプ・メジャーコンパクション
ダンプ
ダンプには、Mini CompactionとMinor Compactionの2つのプロセスが含まれます。メモリ内のMemTableのサイズが一定のしきい値を超えると、MemTable内のデータをディスク上のMini SSTableにダンプしてメモリを解放する必要があります。このプロセスをMini Compactionと呼びます。ユーザーデータの書き込みに伴い、Mini SSTableの数が増え続けます。Mini SSTableの数が一定のしきい値を超えると、バックグラウンドで自動的にMinor Compactionがトリガーされます。
メジャーコンパクション
メジャーコンパクション、またはMajor Compactionは、OceanBaseデータベースでは日次メジャーコンパクションとも呼ばれ、他のLSMツリー型データベースとは概念が若干異なります。その名の通り、この概念が生まれた当初は、毎日午前2時頃にクラスタ全体で一括してCompactionを行うことを想定していました。メジャーコンパクションは通常、各テナントのRSが書き込み状況やユーザー設定に基づいてスケジュールを開始します。各テナントの各メジャーコンパクションでは、グローバルなスナップショットポイントが選択され、テナント内のすべてのパーティションがこのスナップショットポイントのデータを使用してMajor Compactionを行います。このように、毎回のメジャーコンパクションでは、テナントのすべてのデータがこの統一されたスナップショットポイントに基づいて対応するSSTableが生成されます。この仕組みにより、ユーザーは定期的に増分データを統合し、読み取り性能を向上させることができるだけでなく、自然なデータ検証ポイントも提供されます。グローバルな整合性のある時点を利用することで、OceanBaseデータベースは内部でマルチレプリカや主表・インデックス表に対して多次元的な物理データ検証を行うことができます。
クエリの読み書き
挿入
OceanBaseデータベースでは、すべてのデータテーブルはインデックス集約テーブルと見なすことができます。主キーのないヒープテーブルであっても、内部では隠れた主キーが維持されます。したがって、ユーザーがデータを挿入する際には、新しいユーザーデータをMemTableに書き込む前に、現在のデータテーブルに同じデータの主キーが既に存在するかどうかを確認する必要があります。この繰り返し主キー検索のパフォーマンスを向上させるため、各SSTableに対して、バックグラウンドスレッドが異なるマクロブロックの重複頻度に応じてBloomfilterの構築を非同期でスケジュールします。
更新
LSMツリー型データベースとして、OceanBaseデータベースにおける各更新も新しいデータ行を挿入することになります。Clogとは異なり、MemTableで更新されたデータの書き込みには、更新列の新しい値と対応する主キー列のみが含まれます。つまり、更新行には必ずしもテーブルのすべての列のデータが含まれるわけではありません。継続的なバックグラウンドCompactionの動作により、これらの増分更新が絶えず統合され、ユーザーのクエリが高速化されます。
削除
更新と同様に、削除操作も元のデータに直接作用するのではなく、削除行の主キーを使用して新しいデータ行を書き込み、行ヘッダーマーカーで削除操作を示します。大量の削除操作はLSMツリー型データベースにとって好ましくありません。これにより、データ範囲が完全に削除された後でも、データベースはその範囲内のすべての削除マーク行を反復処理し、統合後に初めて削除状態を確認する必要があります。このようなシナリオに対処するため、OceanBaseデータベースは内在的な範囲削除マーカーロジックを提供し、このような状況を回避します。また、ユーザーが明示的にテーブルモードを指定することもサポートしており、特殊なダンプ・メジャーコンパクション方式を通じてこれらの削除行を事前に回収し、クエリを高速化することができます。
クエリ
増分更新の戦略により、各行データをクエリする際には、バージョンの新旧に応じてすべてのMemTableおよびSSTableを走査し、各テーブルの対応する主キーのデータを統合して返す必要があります。データアクセスプロセスでは、必要に応じてCacheを利用して高速化されます。また、大規模クエリシナリオに対応するため、SQL層はフィルター条件をストレージ層にプッシュダウンし、ストレージデータの特性を活用して低レイヤーでの高速フィルタリングを実現します。また、ベクトル化シナリオでのバッチ計算と結果返却もサポートしています。
多層キャッシュ
パフォーマンス向上のため、OceanBaseデータベースは多層キャッシュシステムをサポートしています。クエリに対しては、データマイクロブロックに対するBlock Cache、各SSTableに対するRow Cache、クエリ統合結果に対するFuse Row Cache、挿入時のNULLチェック用Bloomfilter cacheなどが提供されます。同一テナント内のすべてのキャッシュはメモリを共有しており、MemTableへの書き込み速度が速すぎる場合、現在の各種キャッシュオブジェクトから柔軟にメモリを割り当てて書き込みに使用することができます。
データ検証
金融級リレーショナルデータベースとして、OceanBaseデータベースは常にデータ品質とセキュリティを最優先事項としています。データ永続化に関わる全データリンクの各段階でデータ検証保護が追加されており、同時にマルチレプリカストレージの内在的利点を活用して、レプリカ間のデータ検証も追加し、全体のデータ一貫性をさらに検証します。
論理検証
一般的なデプロイメントモードでは、OceanBaseデータベースの各ユーザーテーブルには複数のレプリカが存在します。テナントの日次メジャーコンパクション時には、すべてのレプリカがグローバル統一のスナップショットバージョンに基づいて一貫したベースラインデータを生成します。この特性を利用して、メジャーコンパクション完了時には、すべてのレプリカのデータのチェックサムを比較し、完全な一致性を保証します。さらに進んで、ユーザーテーブルのインデックスに基づき、インデックス列のチェックサムも比較し、最終的にユーザーに返されるデータがプログラムの内在的問題で誤っていないことを確認します。
物理検証
データストレージに関しては、OceanBaseデータベースはデータストレージの最小I/O粒度であるマイクロブロックから始め、各マイクロブロック/マクロブロック/SSTable/パーティションごとに対応するチェックサムを記録します。データ読み取りのたびにデータ検証が実行されます。また、基盤ストレージハードウェアの問題を防ぐため、ダンプやメジャーコンパクションによるデータマクロブロックへの書き込み時にも、書き込み後すぐに再度データを検証します。最後に、各サーバーのバックグラウンドでは定期的なデータ巡回スレッドが全体的なデータをスキャン・検証し、ディスクのサイレントデータ損失を早期に発見します。