ApsaraDB RDS for MySQL のノンブロッキング DDL 機能は、データ定義言語 (DDL) 操作がメタデータロック (MDL) を取得できない場合に、セッションブロッキングやコネクションの滞留を防ぎます。これにより、DDL 実行中のインスタンスの安定性と可用性が向上します。
仕組み
背景:MySQL では、DDL 操作はメタデータの一貫性を確保するために、対象テーブルに対して排他メタデータロック (MDL-X) を取得する必要があります。テーブルに未コミットのトランザクションや長時間実行クエリが存在する場合、DDL スレッドはロックを即座に取得できないため、待機状態になります。待機中の MDL-X ロックは最も高い優先度を持つため、対象テーブルへの後続のすべてのアクセスをブロックします。これにより、セッションブロッキング、コネクションの滞留、および応答の遅延が発生する可能性があります。深刻な場合には、ビジネスシステム全体が利用できなくなることもあります。
概要:ApsaraDB RDS for MySQL のノンブロッキング DDL 機能は、DDL スレッドがメタデータロック (MDL) を取得し、待機する方法を変更します。この機能は、1 回の長い待機を、断続的な短い待機の連続に置き換えます。待機の間隔中に、DDL スレッドは MDL-X ロックのリクエストを解放し、新しいセッションが対象テーブルにアクセスできるようにします。これにより、DDL スレッドが他のセッションによる対象テーブルへのアクセスを長期間ブロックするのを防ぎます。
使用上の注意
ノンブロッキング DDL 機能を使用するには、インスタンスが次のいずれかのバージョン要件を満たす必要があります。インスタンスが要件を満たしていない場合は、マイナーエンジンバージョンのアップグレードまたはメジャーデータベースバージョンのアップグレードが可能です。
MySQL 8.4
マイナーエンジンバージョンが 20250531 以降の MySQL 8.0
ノンブロッキング DDL 機能には、次の制限事項があります。
ALTER TABLE、CREATE INDEX、およびDROP INDEXの操作のみがサポートされています。OPTIMIZE TABLEの操作を実行するには、代わりにALTER TABLE ... ENGINE = InnoDBを使用します。この機能は、プライマリノードからデータが同期される際、セカンダリノードおよび読み取り専用インスタンスでは有効になりません。
この機能を有効にすると、DDL 操作の優先度が低下します。これにより、メタデータロック (MDL) を取得できずに DDL 操作が失敗する可能性が高くなります。
パラメータ管理
パラメータ
loose_rds_nonblock_ddl_retry_interval および loose_rds_nonblock_ddl_lock_wait_timeout パラメーターを使用して、非ブロッキング DDL 機能を制御および調整できます。この機能が有効になると、DDL スレッドは断続的にメタデータロック (MDL) の取得を試みます。試行が失敗した場合、スレッドは MDL リクエストを解放し、待機してから再試行します。
パラメータ | 説明 |
|
|
|
|
パラメータの変更
- RDSインスタンスにアクセスし、上部のリージョンを選択し、対象のRDSインスタンスのIDをクリックします。
左側のナビゲーションペインで、[パラメータ] をクリックします。
[編集可能なパラメータ] タブで、変更するパラメータを検索し、その値を変更します。
[OK] をクリックし、次に [パラメータの送信] をクリックします。ダイアログボックスで、変更が有効になるタイミングを指定します。
機能の有効性
テスト方法
このテストでは、sysbench を使用して、ノンブロッキング DDL 機能を使用した場合と使用しない場合の DDL 操作のパフォーマンスへの影響を比較します。次の手順を実行します。
sysbench を使用してテーブルを作成し、データを挿入します。
sysbench oltp_read_write --db-ps-mode=auto --percentile=95 --mysql-host=$HOST --mysql-port=$PORT --mysql-user=$USER --mysql-db=$DB --tables=1 --table-size=50 --threads=16 preparesysbench のストレステストを開始して、オンラインビジネストラフィックをシミュレートします。
sysbench oltp_read_write --db-ps-mode=auto --percentile=95 --mysql-host=$HOST --mysql-port=$PORT --mysql-user=$USER --mysql-db=$DB --tables=1 --table-size=50 --threads=16 --report-interval=1 --time=100 run別のセッションで、後続の DDL 操作をブロックするために、対象テーブルで長時間実行トランザクションを開始します。
SELECT SLEEP(60) FROM sbtest1 LIMIT 1;別のセッションで、ノンブロッキング DDL 機能を無効にした状態で、次の DDL 操作を実行し、秒間トランザクション数 (TPS) の変化を観察します。
ALTER TABLE sbtest1 ENGINE = InnoDB; -- 想定される結果:DDL スレッドはメタデータロック (MDL) を取得できないため、ブロックされます。loose_rds_nonblock_ddl_retry_intervalパラメーターを 6 に、loose_rds_nonblock_ddl_lock_wait_timeoutパラメーターを 1 に設定して非ブロッキング DDL 機能を有効にし、同じ DDL 操作を実行して TPS の変化を確認します。ALTER TABLE sbtest1 ENGINE = InnoDB; -- 想定される結果:DDL スレッドは断続的にメタデータロック (MDL) の取得を試みるため、完全にはブロックされません。
テスト結果
ノンブロッキング DDL 機能が無効の場合、DDL スレッドはメタデータロック (MDL) を取得できず、セッションは完全にブロックされます。
ノンブロッキング DDL 機能が有効の場合、DDL スレッドは断続的にメタデータロック (MDL) の取得を試みます。これにより、セッションが完全にブロックされるのを防ぎ、システムの安定性が維持されます。

