PolarDB は、DDL 文の実行時に長時間ロック待ちによって発生する輻輳を回避できるノンブロッキング DDL 文をサポートしています。このトピックでは、ノンブロッキング DDL 文について説明します。
背景情報
ブロッキング DDL 文が発行され、影響を受けるテーブルにコミットされていないトランザクションまたはクエリがある場合、DDL 文は MDL-X ロックを待ち続けます。DDL 文が待機している間も、同じテーブルのデータを操作するトランザクションは引き続き発行される可能性があります。ただし、MDL-X ロックは最優先されるため、新しいトランザクションはこのブロッキング DDL 文が完了するまで待機する必要があります。その結果、接続が輻輳し、ビジネスシステム全体に障害が発生する可能性があります。ただし、この DDL 文がノンブロッキング DDL 文の場合、文が MDL-X ロックを待機している間も、新しく発行されたトランザクションは引き続き実行できます。
前提条件
PolarDB for MySQL クラスタが、次のいずれかの要件を満たしていること。
リビジョンバージョンが 8.0.1.1.29 以後の PolarDB for MySQL 8.0.1 のクラスタ。
リビジョンバージョンが 8.0.2.2.12 以後の PolarDB for MySQL 8.0.2 のクラスタ。
クラスタのバージョンの確認方法については、「エンジンバージョン 5.6、5.7、および 8.0」をご参照ください。
注意事項
ノンブロッキング DDL 文は優先度が低く、MDL ロックがないために失敗する可能性が高くなります。
制限事項
リビジョンバージョンが 8.0.1.1.29 以後の PolarDB for MySQL 8.0.1 のクラスタ、または PolarDB for MySQL 8.0.2.2.12 のクラスタ:
ALTER TABLE 文のみがノンブロッキング DDL 機能をサポートしています。この機能は、
ALTER TABLE table_name ADD INDEX index_name ( 'column1', 'column2', 'column3')文に最適です。InnoDB エンジンで作成されたテーブルをデフラグするには、
OPTIMIZE TABLE table_name文ではなく、ALTER TABLE table_name engine=innodb文を実行する必要があります。
リビジョンバージョンが 8.0.2.2.13 以後の PolarDB for MySQL 8.0.2 クラスタ。
ALTER TABLE、OPTIMIZE TABLE、および TRUNCATE TABLE 文は、ノンブロッキング DDL 機能をサポートしています。
ノンブロッキング DDL 文の使用
次の表に、ノンブロッキング DDL 文を使用するためのパラメータを示します。詳細については、「クラスタとノードのパラメータを設定する」をご参照ください。
パラメータ | レベル | 説明 |
loose_polar_nonblock_ddl_mode | セッション | ノンブロッキング DDL 機能を有効にするかどうかを指定します。デフォルト値: OFF。有効な値:
|
loose_polar_nonblock_ddl_retry_times | セッション | DDL 文が MDL-X ロックの取得を試みてタイムアウトした後に許可される最大再試行回数。有効な値: 0 ~ 31536000。デフォルト値: 0。 説明 このパラメータの値を 4194304 に設定することをお勧めします。 |
loose_polar_nonblock_ddl_retry_interval | セッション | DDL 文が MDL-X ロックの取得を再試行する間隔。有効な値: 1 ~ 31536000。単位: 秒。デフォルト値: 6。 |
loose_polar_nonblock_ddl_lock_wait_timeout | セッション | DDL 文が MDL-X ロックの取得を試みるタイムアウト期間。有効な値: 1 ~ 31536000。単位: 秒。デフォルト値: 1。 |
パフォーマンステスト
このセクションでは、ブロッキング DDL 文の使用、ノンブロッキング DDL 文の使用、および gh-ost を使用したスキーマ変更のパフォーマンスを比較します。
テストツール
SysBench は、モジュール式、クロスプラットフォーム、マルチスレッドのベンチマークツールであり、コアメトリックに基づいて高負荷のデータベースシステムのパフォーマンスを評価するために使用できます。 SysBench を使用すると、データベースをインストールしていなくても、複雑なベンチマーク設定なしでデータベースのパフォーマンスをすばやくテストできます。 SysBench の使用方法については、「OLTP パフォーマンステスト」をご参照ください。
テスト環境
8 CPU コアと 64 GB メモリを搭載した PolarDB for MySQL 8.0 クラスタ。クラスタはクラスタ版で実行されています。
テスト方法
SysBench を使用して、
sbtest1という名前のテストテーブルを作成し、テーブルに 100 万行のデータを挿入します。./oltp_read_write.lua --mysql-host="クラスタエンドポイント" --mysql-port="ポート番号" --mysql-user="ユーザー名" --mysql-password="パスワード" --mysql-db="sbtest" --tables=1 --table-size=1000000 --report-interval=1 --percentile=99 --threads=8 --time=6000 prepareoltp_read_write.luaスクリプトを使用して、ユーザービジネスをシミュレートします。./oltp_read_write.lua --mysql-host="クラスタエンドポイント" --mysql-port="ポート番号" --mysql-user="ユーザー名" --mysql-password="パスワード" --mysql-db="sbtest" --tables=1 --table-size=1000000 --report-interval=1 --percentile=99 --threads=8 --time=6000 runsbtest1テーブルでトランザクションを開始しますが、トランザクションをコミットしないでください。これにより、トランザクションはテーブルへの MDL ロックを保持します。/* session 1 */ begin; select * from sbtest1;別のセッションで、
sbtest1テーブルに列を追加し、TPS の変化を監視します。/* session 2 */ alter table sbtest1 add column d int;gh-ost ツールを使用して列を追加し、TPS の変化を監視します。バイナリログは、パフォーマンス監視に使用されます。詳細については、「バイナリロギングを有効にする」をご参照ください。
./gh-ost --assume-rbr --user="ユーザー名" --password="パスワード" --host="クラスタエンドポイント" --port="ポート番号" --database="sbtest" --table="sbtest1" --alter="ADD COLUMN d INT" --allow-on-master --aliyun-rds --initially-drop-old-table --initially-drop-ghost-table --execute;
テスト結果
ノンブロッキング DDL 文が無効になっている場合、TPS はゼロに低下し、長期間ゼロのままになります。ビジネスに深刻な影響があります。

ノンブロッキング DDL 文が有効になっている場合、TPS は定期的に低下しますが、ゼロには低下しません。ロック待機はビジネスにわずかな影響しか与えず、システムの安定性が確保されます。

gh-ost を使用してテーブルスキーマを変更する場合、TPS は定期的にゼロに低下します。この場合、カットオーバーステップでの一時テーブルロックが原因で、ビジネスに深刻な影響があります。

ノンブロッキング DDL 文と Gh-ost ツールの性能比較
このセクションでは、INSTANT、INPLACE、COPY などのノンブロッキング DDL 文と gh-ost ツールを使用して、1 億行のデータを含むテーブルに列を追加します。パフォーマンスを比較します。
テーブルにワークロードがない場合、ノンブロッキング DDL 文は gh-ost ツールよりも高速です。

SysBench の oltp_read_write スクリプトを使用してビジネスワークロードをシミュレートする場合でも、ノンブロッキング DDL 文は gh-ost ツールよりも高速です。

結論
ノンブロッキング DDL 文は、新しいトランザクションをブロックせず、TPS がゼロになるのを回避します。これにより、システムの安定性が最大限に向上し、DDL 文の効率が向上します。
お問い合わせ
DDL 操作についてご質問がある場合は、お問い合わせください。