主キーの追加、セカンダリインデックスの追加、OPTIMIZE TABLE の実行など、B-tree インデックスを再構築する DDL 操作は、大量のリドログを生成します。プライマリノードでは、これらのリドログの書き込みがボトルネックとなり、DDL 実行の遅延を引き起こします。また、読み取り専用ノードでは、同一のリドログの解析および適用に時間がかかり、深刻なレプリケーションラグを生じます。さらに、同時実行 DDL ワークロード下では、読み取り専用ノードが利用不能になる場合があります。
DDL 物理レプリケーション最適化機能は、この問題を解決するために、プライマリノードにおけるリドログ書き込みパスと、読み取り専用ノードにおけるリドログ適用パスの両方を最適化します。本機能を有効化すると、プライマリノードでの主キー追加処理時間はベースライン比で約 20.6 % に短縮され、読み取り専用ノードにおけるレプリケーション遅延はベースライン比で約 0.4 % まで低減されます。
前提条件
開始前に、クラスターが以下のいずれかのバージョン要件を満たしていることを確認してください。現在のバージョンを確認するには、「エンジンバージョン」をご参照ください。
PolarDB for MySQL 8.0.1(リビジョンバージョン 8.0.1.1.10 以降)
PolarDB for MySQL 5.7(リビジョンバージョン 5.7.1.0.10 以降)
仕組み
PolarDB はコンピューティングとストレージを分離しています。プライマリノードと読み取り専用ノードは、同一の基盤データを共有し、バイナリログではなくリドログを伝播することで物理レプリケーションを実現し、一貫性を保ちます。これにより、バイナリログに対する fsync 操作に起因する I/O オーバーヘッドも低減されます。
InnoDB はデータを B-tree インデックスに格納します。主キーの追加、セカンダリインデックスの作成、OPTIMIZE TABLE の実行など、B-tree インデックスを作成または再構築する DDL 操作は、多数のリドログを生成します。最適化が適用されていない場合:
リドログの書き込みが、プライマリノードにおける DDL 実行パス上のボトルネックとなります。
読み取り専用ノードは、一貫した読み取りサービスを提供する前に、すべてのリドログを解析・適用する必要があり、これによりレプリケーションラグが発生します。同時に複数の DDL を実行するワークロード下では、このラグがカスケード的にノードの利用不能を引き起こす可能性があります。
DDL 物理レプリケーション最適化機能は、プライマリノードにおけるリドログ書き込みを効率化し、読み取り専用ノードが DDL 生成リドログを適用するために行う処理量を削減することで、上記のボトルネックを解消します。
制限事項
対応する DDL 操作:主キーおよびセカンダリインデックスの作成のみ。全文検索インデックスおよび空間インデックスは非対応です。
RENAME TABLEなどのメタデータのみを変更する DDL 操作は、リソース消費が極めて少なく、デフォルトで高速であるため、本機能を必要としません。PolarDB for MySQL 8.0.2 および 5.6 では非対応です。
DDL 物理レプリケーション最適化の有効化
本機能を有効化するには、以下のパラメーターをグローバルレベルで設定します。
| パラメーター | レベル | デフォルト値 | 説明 |
|---|---|---|---|
innodb_bulk_load_page_grained_redo_enable | グローバル | OFF | DDL 物理レプリケーション最適化を制御します。ON に設定すると有効化されます。 |
パフォーマンス結果
以下のテストは、1 台のプライマリノードと 1 台の読み取り専用ノードから構成される PolarDB for MySQL 8.0 クラスター(16 コア CPU、128 GB メモリ、50 TB ストレージ)で実施しました。
テスト構成
スキーマ:
CREATE TABLE t0(a INT PRIMARY KEY, b INT) ENGINE=InnoDB;データ: 100 万件、1,000 万件、1 億件、10 億件のランダム値を含むテーブル:
DELIMITER //
CREATE PROCEDURE populate_t0()
BEGIN
DECLARE i int DEFAULT 1;
WHILE (i <= $table_size) DO
INSERT INTO t0 VALUES (i, 1000000 * RAND());
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
CALL populate_t0();$table_sizeを挿入する行数(例:1000000)に置き換えてください。
テスト対象の DDL 操作:
ADD PRIMARY KEYADD INDEX(セカンダリインデックス)OPTIMIZE TABLE
テスト 1:プライマリノードにおける DDL 実行時間
ADD PRIMARY KEY および OPTIMIZE TABLE の実行時間を、テーブルサイズごとに比較しました。innodb_bulk_load_page_grained_redo_enable を ON および OFF に設定した場合の結果を示します。
主キーの追加:

テーブルの最適化:

テスト 2:並列 DDL との併用
10 億件のテーブルに対して ADD INDEX を実行する際の所要時間を、スレッド数(innodb_polar_parallel_ddl_threads を 1、2、4、8、16、32 に設定)ごとに比較しました。innodb_bulk_load_page_grained_redo_enable を ON および OFF に設定した場合の結果を示します。
並列 DDL が有効な場合(innodb_polar_use_sample_sort および innodb_polar_use_parallel_bulk_load の両方が有効):

並列 DDL が無効な場合(innodb_polar_use_sample_sort および innodb_polar_use_parallel_bulk_load の両方が無効):

並列 DDL のパラメーターについて詳しくは、「並列 DDL」をご参照ください。
テスト 3:同時実行 DDL 下における読み取り専用ノードの安定性
プライマリノードで 10 億件のテーブルに対して 1、2、4、6、8 件の同時実行 DDL 操作を実行した際の、読み取り専用ノードのステータス、CPU 使用率、メモリ使用率、IOPS、およびレプリケーション遅延をテストしました。
本機能が有効な場合(innodb_bulk_load_page_grained_redo_enable = ON):
| 同時実行 DDL 操作数 | 1 | 2 | 4 | 6 | 8 |
|---|---|---|---|---|---|
| 読み取り専用ノードのステータス | 正常 | 正常 | 正常 | 正常 | 正常 |
| ピーク CPU 使用率 (%) | 1.86 | 1.71 | 1.76 | 2.25 | 2.36 |
| ピークメモリ使用率 (%) | 10.37 | 10.80 | 10.88 | 11 | 11.1 |
| 読み取り IOPS(1 秒あたりの読み取り回数) | 10965 | 10762 | 10305 | 10611 | 10751 |
| ピークレプリケーション遅延 (s) | 0 | 0.73 | 0.87 | 0.93 | 0.03 |
本機能が無効な場合(innodb_bulk_load_page_grained_redo_enable = OFF):
4 件の同時実行 DDL 操作については、読み取り専用ノードが利用不能になる直前のデータを示しています。ハイフン(-)は、その同時実行数で DDL 操作が失敗し、結果が返されなかったことを示します。
| 同時実行 DDL 操作数 | 1 | 2 | 4 | 6 | 8 |
|---|---|---|---|---|---|
| 読み取り専用ノードのステータス | 正常 | 正常 | 利用不能 | 利用不能 | 利用不能 |
| ピーク CPU 使用率 (%) | 4.2 | 9.5 | 10.3 | - | - |
| ピークメモリ使用率 (%) | 22.15 | 23.55 | 68.61 | - | - |
| 読み取り IOPS(1 秒あたりの読み取り回数) | 9243 | 7578 | 7669 | - | - |
| ピークレプリケーション遅延 (s) | 0.8 | 14.67 | 211 | - | - |
本機能が無効な場合、4 件以上の同時実行 DDL 操作で読み取り専用ノードが利用不能になり、4 件の同時実行時にレプリケーション遅延が最大 211 秒に達します。一方、本機能を有効化すると、すべての同時実行数においてノードは正常に動作し、レプリケーション遅延は 1 秒未満に抑えられます。
お問い合わせ
DDL 操作に関するご質問がある場合は、「テクニカルサポート」までお問い合わせください。