高い同時実行性環境下の MySQL でバイナリラージオブジェクト (BLOB) を書き込むと、ロック競合や REDO ログのボトルネックなどのパフォーマンス問題が発生する可能性があります。PolarDB for MySQL は、書き込み、更新、領域解放など、BLOB データのライフサイクル全体を改善するカーネルレベルの最適化でこれらの課題に対処します。これらの機能は、データ操作言語 (DML) とデータ定義言語 (DDL) の両方の操作のパフォーマンスを大幅に向上させ、高い同時実行性のワークロード下でアプリケーションが効率的に実行されることを保証します。
仕組み
BLOB は、画像、ドキュメント、または長いテキストなどのラージオブジェクトを格納するために使用されるデータの型です。ネイティブの MySQL InnoDB エンジンでは、BLOB が特定のサイズを超えると、別の外部データページ (オフページ) に格納されます。このメカニズムは、主に 3 つのパフォーマンス上の課題を生み出します。
同時書き込みのボトルネック: オフページの BLOB を更新すると、悲観ロックがトリガーされます。これにより、一度に 1 つのスレッドしか単一テーブルで BLOB の書き込みを実行できなくなり、同時実行性が大幅に制限されます。
I/O プレッシャーの増大: ラージオブジェクトフィールドは、大量の REDO ログを生成します。ディスク I/O が不十分な場合、ログのフラッシュがボトルネックとなり、フォアグラウンドの書き込みをブロックします。
領域解放の遅延: 古い BLOB データのクリーンアップ (パージ) は非効率的です。これにより、ストレージ領域の肥大化とパフォーマンスの低下につながる可能性があります。
PolarDB の最適化は、アプリケーションが BLOB を使用する方法を変更することなく、カーネルレベルでこれらの問題を解決します。以下の図は、その仕組みを示しています。
課金
BLOB パフォーマンス最適化機能は PolarDB カーネルに組み込まれており、無料で利用できます。
BLOB 書き込みパフォーマンスの最適化
ピークの営業時間中に BLOB テーブルへの同時書き込みで、書き込みスループットのボトルネックや高い待機時間が発生する場合、その原因は通常、書き込みロックの競合です。PolarDB は、この問題を解決するために、ページの事前割り当てとインデックスラッチの最適化を提供します。
ページの事前割り当て
この最適化により、BLOB の書き込みプロセスが、より高速で同時実行性の高いステップに分割されます。
必要なすべてのデータページを計算し、単一のバッチでリクエストします。
ロックなしでデータをコピーし、新しく割り当てられたページを BLOB コンテンツで埋めます。
単一の楽観的ロック操作を使用して、生成されたデータページチェーンをインデックスレコードにアタッチします。
このプロセス中、排他的なのは最初の領域割り当てフェーズのみです。時間のかかるデータコピー操作は、他の BLOB 書き込みと並行して実行できます。この設計により、グローバルロックが保持される時間が最小限に抑えられ、同時書き込みのスループットが劇的に向上します。
インデックスラッチの最適化
小さい (8 KB 未満) または混合サイズの BLOB を持つテーブルの場合、ネイティブの MySQL は更新中に楽観的ロックを早期に放棄し、非効率的な悲観ロックにフォールバックすることがよくあります。ラッチの最適化は、楽観的なパスでより多くの作業を実行することでこの問題を解決します。
楽観的パスの維持: システムが BLOB フィールドの更新が必要になる可能性を検出した場合、最適化ロジックはすぐに悲観ロックに切り替えません。代わりに、競合の可能性が低い共有ロック (S-latch) を保持し続け、楽観的な更新パスにとどまります。
事前ビルドと更新の試行: 楽観的なパスでは、更新に必要な BLOB データ構造を事前にビルドし、インデックスページを直接変更しようとします。
チェックとコミットまたはロールバック:
成功: 更新されたレコードが現在のインデックスページに収まる場合、操作は楽観的なパスで迅速に完了します。
失敗: ページに十分なスペースがない場合、最適化は自動的に試行を中止します。その後、ネイティブの MySQL の悲観ロックパスにシームレスにロールバックして更新操作を完了し、データ整合性を確保します。
このメカニズムにより、楽観的な更新の成功率が大幅に向上し、高い同時実行性下での混合サイズの BLOB ワークロードのスループットが向上します。
書き込み最適化の有効化
最適化を有効にするには、PolarDB コンソール の ページに移動して、次のパラメーターを 表示および変更 します。
パラメーター | 説明 | サポートされているバージョン |
| BLOB ページの事前割り当て最適化を有効または無効にします。 有効な値:
|
|
| BLOB ページの事前割り当て最適化のために、単一の BLOB 列の最大長を設定します。 | |
| BLOB インデックスラッチの最適化を有効または無効にします。 |
BLOB 書き込みの REDO ログ ボリュームの削減
アプリケーションが大量の BLOB データを書き込み、REDO ログの生成率が I/O ボトルネックになる場合は、REDO 圧縮を有効にして I/O プレッシャーを軽減できます。
この機能は、BLOB の REDO ログレコードをログバッファーに書き込む前に並行して圧縮します。これにより、ディスクに書き込まれる REDO ログの実際のボリュームを平均で 40%~60% 削減でき、I/O プレッシャーを低減し、REDO モジュールが全体の書き込みパフォーマンスに影響を与えるのを防ぎます。ログは、データベースのクラッシュ回復中に自動的に解凍されます。
REDO 圧縮の有効化
最適化を有効にするには、 ページの PolarDB コンソール に移動して、次のパラメーターを 表示および変更 します。
パラメーター | 説明 | サポートされているバージョン |
| BLOB REDO ログの圧縮アルゴリズムを設定します。有効な値:
|
|
| 選択した圧縮アルゴリズムの圧縮レベルを設定します。 値の範囲は 0 から 9 です。デフォルト値は 6 です。 |
BLOB 領域解放の高速化
BLOB データを頻繁に削除または更新した後でもテーブルスペースが増え続ける場合、その原因はネイティブ MySQL の非効率的なバックグラウンドのパージプロセスです。ネイティブのパージプロセスは、BLOB ページを読み取るために潜在的に遅いディスク I/O を実行している間、コアロックを保持します。PolarDB は、このボトルネックを解決するために、これら 2 つの操作を分離します。
ターゲットページの特定: クリーンアップをロックして開始する前に、パージプロセスはまず、解放する必要がある完全な BLOB 外部ページチェーンを特定します。
非同期プリリード: 非同期 I/O リクエストを開始して、まだメモリにないターゲットページをディスクからバッファープールにロードします。
高速クリーンアップ: すべてのページがメモリにロードされた後、パージプロセスは
Index SXなどのコアロックを取得します。その後、メモリ内でのページの解放とメタデータの変更を迅速に実行します。
このメカニズムにより、クリティカルロックを保持しながらディスク I/O を実行することが回避されます。これにより、ロック保持時間が大幅に短縮され、BLOB データの解放効率が向上するだけでなく、バックグラウンドのクリーンアップがフォアグラウンドの操作に与える影響も軽減されます。
パージプリリードの有効化
最適化を有効にするには、 ページの PolarDB コンソール に移動して、次のパラメーターを 表示および変更 します。
パラメーター | 説明 | サポートされているバージョン |
| BLOB パージプロセスのページプリリード最適化を有効または無効にします。 有効な値:
| すべてのバージョンでサポートされています。 |
DDL 実行速度の向上
大量の BLOB データを含むテーブルに対する ALTER TABLE 操作が遅すぎる場合は、DDL 固有の BLOB 最適化を有効にすることで、実行時間を大幅に短縮できます。
ページの事前割り当て最適化: BLOB オーバーフロー列はプライマリテーブルの一部であるため、プライマリテーブルを再構築する DDL 操作には BLOB フィールドの書き込みも含まれます。ページの事前割り当て最適化では、より直接的で簡素化されたロック方法を使用して BLOB データを書き込みます。これにより、複雑な同時実行性の競合を処理するオーバーヘッドが回避され、再構築の効率が大幅に向上します。
ラッチの最適化: 並列 DDL はプライマリキーツリーを分割するため、複数のワーカースレッドが同じデータページで操作することはありません。この最適化は、新しいページの割り当て操作を独立して保護し、他の操作が同時に実行されることを可能にし、効率を向上させます。
REDO の最適化:
ページの集約: データのバルクロード中、システムは各レコードに対して REDO ログを生成する代わりに、ページがいっぱいになった後、データページ全体の変更を単一の大きな REDO レコードとして書き込みます。これにより、REDO 操作の効率が向上します。
集約圧縮: システムは、集約された大きな REDO レコードを圧縮して、DDL プロセス中に生成される REDO ログの量をさらに削減します。
DDL 最適化の有効化
最適化を有効にするには、 ページの PolarDB コンソール に移動して、次のパラメーターを 表示および変更 します。
次の表の一部のパラメーターは手動で変更できません。これらのパラメーターを変更するには、チケットを送信 してお問い合わせください。
パラメーター | 説明 | サポートされているバージョン |
| DDL プロセス中にラージオブジェクトの最適化を有効にするかどうかを指定します。有効な値:
|
|
| DDL プロセス中にインデックスロックの最適化を有効にするかどうかを指定します。有効な値:
|
|
| DDL バルクロード中に REDO ページの集約を有効にするかどうかを指定します。有効な値:
|
|
| DDL バルクロードの REDO 圧縮アルゴリズムを設定します。有効な値:
|
|
| DDL プロセス中の REDO 圧縮の適用対象を設定します。有効な値:
|
|
関連するシステムの最適化
可能な限り最高のパフォーマンスを達成するために、PolarDB は、高スループットの BLOB シナリオでボトルネックになる可能性のある関連システムモジュールも最適化します。
並列非同期 REDO 書き込み: システムは REDO バッファー内のデータをシャーディングし、複数のスレッドを使用して非同期 I/O タスクを同時に発行します。これにより、REDO ログの書き込みスループットが大幅に向上し、テストでは最大 4 GB/s を達成しました。
ファイル拡張の最適化: PolarDB が自社開発した分散ファイルシステムに基づき、表領域の拡張操作では少量のメタデータを変更するだけで済みます。ネイティブのファイルのゼロフィル操作が削除されるため、ファイル拡張の時間とロックのオーバーヘッドはもはやボトルネックにはなりません。
ロックフリーのダーティページフラッシュ: システムはシャドウページテクノロジーを使用します。ダーティページをフラッシュするとき、まずメモリ内にコピーを構築し、ページロックを解放してから、そのコピーを I/O 操作に使用します。これにより、ダーティページフラッシュ中にページロックを保持することによる書き込みリクエストのブロックが回避されます。
パフォーマンスデータ
以下のデータは、BLOB 最適化を有効にした後の DML および DDL シナリオでのパフォーマンスの向上を示しています。
DML パフォーマンス 行長が 100 KB と 200 KB の高い同時実行性シナリオでは、PolarDB の挿入と更新の最適化ソリューションにより、パフォーマンスが約 3 倍向上します。REDO 圧縮と組み合わせると、パフォーマンスは 4 倍から 5 倍に向上します。


DDL パフォーマンス BLOB フィールドを含む 40 GB のテーブルの場合、最適化を有効にすると、DDL の書き込みレートが 5 倍から 6 倍に増加し、総実行時間が 84% 短縮されます。
