ダンプと比較して、メジャーコンパクションは一般的に重要な操作であり、時間も比較的長くかかります。ベストプラクティスでは、1日に1回のみメジャーコンパクションを実行し、業務のオフピーク時に行うことが望まれています。そのため、メジャーコンパクションは「日次メジャーコンパクション」と呼ばれることもあります。
メジャーコンパクション(Major Compaction)は、動的および静的データをマージする作業であり、時間がかかります。ダンプによって生成された増分データが一定量に達すると、Major Freezeを経て大規模なバージョンのメジャーコンパクションが実行されます。メジャーコンパクションとダンプの最大の違いは、メジャーコンパクションがテナントの統一されたスナップショットポイントと対応する静的データをマージする行為であり、最終的にテナントレベルのスナップショットを形成する点です。
ダンプ(Mini Compaction) |
ダンプ(Minor Compaction) |
メジャーコンパクション(Major Compaction) |
|---|---|---|
| パーティションまたはテナントレベルで、MemTableのマテリアライズのみが行われる | パーティションレベル | テナントレベルで、テナントレベルのスナップショットが生成される |
| 各OBServerノード上の各テナントは、自身のMemTableのフリーズ操作を独立して決定し、プライマリ/スタンバイパーティション間で一貫性は保たれない | 各パーティションは、現在のSSTable(Mini SSTableとMinor SSTableを含む)の数に基づいて、パーティション内のMinor Compactionを実行する | テナントのすべてのパーティションが一緒にMemTableのフリーズ操作を行い、プライマリ/スタンバイパーティション間で一貫性を保つ必要がある。メジャーコンパクション時にデータの整合性検証が行われる。 |
| 複数の異なるバージョンのデータ行を含む可能性がある | 複数の異なるバージョンのデータ行を含む可能性がある | スナップショットポイントのバージョン行のみを含む |
| 1つまたは複数のMemTableをMini SSTableに永続化する | 複数のMini SSTableを1つのMini SSTableに合併するか、複数のMini SSTableと1つのMinor SSTableを合併して新しいMinor SSTableを生成する。このMinor 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データベースのストレージエンジンでは、マクロブロックがOceanBaseデータベースの基本的なI/O書き込み単位です。多くの場合、すべてのマクロブロックが変更されるわけではありません。マクロブロックに増分変更がない場合、メジャーコンパクションではこのデータマクロブロックを直接再利用することができます。OceanBaseデータベースでは、このようなメジャーコンパクション方式を増分コンパクションと呼んでいます。増分コンパクションはメジャーコンパクションの作業量を大幅に削減し、現在のOceanBaseデータベースのデフォルトのメジャーコンパクションアルゴリズムです。さらに進んで、OceanBaseデータベースはマクロブロック内部でデータをより小さなマイクロブロックに分割します。多くの場合、すべてのマイクロブロックが変更されるわけではなく、マイクロブロックを書き直す代わりに再利用することができます。マイクロブロックレベルの増分コンパクションにより、メジャーコンパクションの時間がさらに短縮されます。
減進的メジャーコンパクション
業務の急速な発展を支えるため、ユーザーは避けられずに列の追加、削除、インデックスの作成など、多くのDDL変更を行うことになります。これらのDDL変更は、データベースにとって通常は高コストな操作です。MySQLは長い間、オンラインDDL変更をサポートしていませんでした(5.6バージョンでようやくOnline DDLに対するサポートが向上し始めました)。そして今日に至るまで、DBAにとって、MySQL 5.7でOnline DDLを行うことは依然としてリスクの高い操作です。なぜなら、大規模なDDL変更はMySQLのプライマリ/スタンバイ間のreplication lagを引き起こす可能性があるからです。
OceanBaseデータベースは設計段階からOnline 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;
関連ドキュメント
その他のコンパクション操作については、コンパクションを参照してください。