ダンプと比較して、メジャーコンパクションは一般的に重要な操作であり、時間も比較的長くかかります。ベストプラクティスでは、1日に1回のみメジャーコンパクションを実行し、業務のオフピーク時に制御することが望まれています。そのため、メジャーコンパクションは「日次メジャーコンパクション」と呼ばれることもあります。
メジャーコンパクション(Major Compaction)は、動的および静的データをマージする操作であり、時間がかかります。ダンプによって生成された増分データが一定量に達すると、Major Freezeを通じてメジャーバージョンのメジャーコンパクションが実行されます。メジャーコンパクションとダンプの最大の違いは、メジャーコンパクションがテナントの統一されたスナップショットポイントと対応する静的データをマージする行為であり、最終的にはテナントレベルのスナップショットが形成される点です。
ミニコンパクション(Mini Compaction) |
マイナーコンパクション(Minor Compaction) |
メジャーコンパクション(Major Compaction) |
|---|---|---|
| パーティションまたはテナントレベルで、MemTableのマテリアライズのみが行われます | パーティションレベル | テナントレベルで、テナントレベルのスナップショットが生成されます |
| 各OBServerノード上の各テナントは、自身のMemTableのフリーズ操作を独立して決定し、プライマリ/スタンバイパーティション間で一貫性は保たれません | 各パーティションは、現在のSSTable(Mini SSTableとMinor SSTableを含む)の数に基づいて、パーティション内のマイナーコンパクションを実行します | テナントのすべてのパーティションが一緒にMemTableのフリーズ操作を行い、プライマリ/スタンバイパーティション間で一貫性を保つ必要があります。メジャーコンパクション時にデータの整合性検証が行われます。 |
| 複数の異なるバージョンのデータ行を含む可能性があります | 複数の異なるバージョンのデータ行を含む可能性があります | スナップショットポイントのバージョン行のみを含みます |
| 1つまたは複数のMemTableをミニSSTableに永続化します | 複数のミニSSTableを1つのミニSSTableに統合するか、複数のミニSSTableと1つのマイナーSSTableを統合して新しいマイナーSSTableを生成します。これには増分データのみが含まれ、最終的に削除される行は特別なマークが必要です。 | メジャーコンパクションでは、現在の大きなバージョンのSSTableとMemTableを前の大きなバージョンの全量静的データと統合し、新しい全量データを生成します。 |
メジャーコンパクションは時間がかかるものの、同時にデータベースに操作ウィンドウを提供します。このウィンドウ内で、OceanBaseデータベースはメジャーコンパクションの特性を活用して複数の計算集約型タスクを完了し、全体のリソース利用効率を向上させることができます。
データ圧縮
メジャーコンパクション中、OceanBaseデータベースはデータに対して2段階の圧縮を行います。第1段階はデータベース内部での意味ベースのエンコード圧縮であり、第2段階はユーザーが指定した圧縮アルゴリズムに基づく汎用的な圧縮で、LZ4などの圧縮アルゴリズムを使用してエンコード後のデータをさらに圧縮します。圧縮はストレージ容量を節約するだけでなく、クエリ性能も大幅に向上させます。現在、OceanBaseデータベースはSNAPPY、LZ4、LZO、ZSTDなどの圧縮アルゴリズムをサポートしており、ユーザーは圧縮率と解凍時間の間でトレードオフを行うことができます。MySQLやOracleもある程度データ圧縮をサポートしていますが、OceanBaseと比較すると、従来のデータベースの固定長ページ設計により、圧縮は避けられずにストレージの空洞化を引き起こし、圧縮効率が低下します。さらに重要なのは、OceanBaseデータベースのようなLSM-Treeアーキテクチャのストレージシステムでは、圧縮がデータ書き込み性能にほとんど影響しないことです。
データ検証
テナントレベルの一貫性スナップショットを用いたメジャーコンパクションにより、OceanBaseデータベースは複数レプリカのデータ一貫性検証を容易に行うことができます。メジャーコンパクション完了後、複数のレプリカはベースラインデータと直接比較することで、異なるレプリカ間で業務データが一致していることを確保できます。また、このスナップショットベースラインデータを基に、メインテーブルとインデックステーブルのデータ検証を行い、データがメインテーブルとインデックステーブル間で一致していることを保証できます。
スキーマ変更
列の追加や削除などのスキーマ変更について、OceanBaseデータベースはメジャーコンパクション中にデータ変更操作を一括して完了することができ、DDL操作による業務への影響をよりスムーズにします。
メジャーコンパクションの方式
メジャーコンパクションにはさまざまな方式があり、具体的な内容は以下のとおりです。
フルコンパクション
フルコンパクションはOceanBaseデータベースの初期のメジャーコンパクションアルゴリズムで、HBaseやRocksDBのMajor Compactionプロセスと類似しています。フルコンパクションでは、現在の静的データをすべて読み出し、メモリ内の動的データとマージした後、新しい静的データとしてディスクに書き込みます。このプロセスでは、すべてのデータが書き直されます。フルコンパクションはディスクI/Oとストレージ容量を大幅に消費するため、DBAが強制的に指定する場合を除き、現在のOceanBaseデータベースは通常、自発的にフルコンパクションを実行することはありません。
増分コンパクション
OceanBaseデータベースのストレージエンジンでは、マクロブロックが基本的なI/O書き込み単位です。多くの場合、すべてのマクロブロックが変更されるわけではありません。マクロブロックに増分変更がない場合、メジャーコンパクションではそのデータマクロブロックを直接再利用できます。OceanBaseデータベースでは、このようなメジャーコンパクション方式を増分コンパクションと呼んでいます。増分コンパクションはメジャーコンパクションの作業量を大幅に削減し、現在のOceanBaseデータベースのデフォルトのメジャーコンパクションアルゴリズムとなっています。さらに進んで、OceanBaseデータベースではマクロブロック内部でデータをより小さなマイクロブロックに分割します。多くの場合、すべてのマイクロブロックが変更されるわけではなく、マイクロブロックを書き直す代わりに再利用できます。マイクロブロックレベルの増分コンパクションにより、メジャーコンパクションの時間がさらに短縮されます。
プログレッシブコンパクション
ビジネスの急速な発展をサポートするため、ユーザーは避けられずに列の追加、列の削除、インデックスの作成など、多くのDDL変更を行うことになります。これらのDDL変更は、データベースにとって通常は非常にコストのかかる操作です。MySQLは長い間、オンラインDDL変更をサポートしていませんでした(5.6バージョンまでオンラインDDLのサポートは限定的でした)。そして今日に至るまで、DBAにとってMySQL 5.7でのオンラインDDLは依然としてリスクの高い操作です。大規模なDDL変更は、MySQLのプライマリ/スタンバイ間のレプリケーション遅延を引き起こす可能性があるからです。
OceanBaseデータベースは設計段階からオンラインDDLのニーズを考慮しており、現在ではOceanBaseデータベースでの列の追加、列の削除、インデックスの作成などのDDL操作は、読み書きをブロックせず、マルチレプリカ間のPaxos同期にも影響しません。列の追加・削除に関するDDL変更はリアルタイムで反映され、ストレージデータへの変更は日次メジャーコンパクション時に行われます。しかし、列の追加・削除など一部のDDL操作では、すべてのデータを書き直す必要があります。もし一度の日次メジャーコンパクション処理ですべてのデータの書き直しが完了すると、ストレージ容量とメジャーコンパクション時間に大きな負担がかかります。この問題を解決するため、OceanBaseデータベースはプログレッシブコンパクションを導入し、DDL変更によるデータの書き直しを複数回の日次メジャーコンパクションに分散して行います。プログレッシブラウンドを60に設定した場合、1回のメジャーコンパクションではデータの60分の1のみが書き直され、60ラウンドのメジャーコンパクション後にデータは全体として書き直されます。プログレッシブコンパクションにより、DBAがDDL操作を実行する負担が軽減され、DDL変更がよりスムーズになります。
メジャーコンパクションのトリガー
メジャーコンパクションのトリガー方法は、自動トリガー、定期トリガー、手動トリガーの3種類です。
テナントのフリーズ(Minor Freeze)回数がしきい値を超えた場合、そのテナントのメジャーコンパクションが自動的にトリガーされます。
パラメータを設定することで、毎日の業務の閑散期に定期的にメジャーコンパクションをトリガーすることもできます。
obclient> ALTER SYSTEM SET major_freeze_duty_time = '02:00' TENANT = t1;以下の運用コマンドを使用して手動でメジャーコンパクションをトリガーすることもできます。
システムテナントが他のテナントのメジャーコンパクションを開始する場合
sysテナントに対してメジャーコンパクションを開始する場合obclient> ALTER SYSTEM MAJOR FREEZE TENANT = sys;すべてのユーザーテナントに対してメジャーコンパクションを開始する場合
obclient> ALTER SYSTEM MAJOR FREEZE TENANT = all_user;すべてのMETAテナントに対してメジャーコンパクションを開始する場合
obclient> ALTER SYSTEM MAJOR FREEZE TENANT = all_meta;テナントt1とt2に対してメジャーコンパクションを開始する場合
obclient> ALTER SYSTEM MAJOR FREEZE TENANT = t1,t2;
ユーザーテナントが自身のテナントのメジャーコンパクションを開始する場合
obclient> ALTER SYSTEM MAJOR FREEZE;
関連ドキュメント
その他のメジャーコンパクション操作については、メジャーコンパクションを参照してください。