ApsaraDB RDS for MySQL は、データ定義言語 (DDL) のロック待ちタイムアウトを制御する機能をサポートしています。この機能は、ヒントを使用して、DDL スレッドがメタデータロック (MDL) を待機するタイムアウト期間を制御します。これにより、MDL の長時間の待機に起因するセッションのブロッキングや接続の滞留を防ぎます。
機能の説明
概要: MySQL では、lock_wait_timeout パラメーターが MDL のタイムアウトを制御します。待機動作を正確に制御する必要がある DDL 操作の場合、実行前にこのパラメーターを明示的に変更する必要があります。ApsaraDB RDS for MySQL は、DDL ステートメントの MDL ロック待ち時間をより簡単かつ直感的に制御する方法を提供します。/*+ WAIT(n) */ および /*+ NO_WAIT() */ を使用して、ステートメント内で直接 MDL ロック待ち時間を指定できます。
利点: 新しい構文を導入するよりも、ヒントを使用する方が互換性に優れています。ヒントはコメントとしてバイナリロギング (binlog) ファイルに書き込まれます。この機能をサポートしていないダウンストリームインスタンスやサブスクリプションサービスでは、パーサーが自動的にヒントを無視します。ヒントは通常のコメントとして扱われるため、SQL 解析エラーやレプリケーションの中断を引き起こすことはありません。
適用範囲
データベースのメジャーバージョンが MySQL 8.0 で、マイナーエンジンバージョンが 20250531 以降の場合にのみ、DDL ロック待ちタイムアウト制御機能を使用できます。ご利用のインスタンスがバージョン要件を満たしていない場合は、マイナーエンジンバージョンまたはデータベースのメジャーバージョンをアップグレードできます。
この機能には、以下の制限事項があります:
CREATE、DROP、ALTER、RENAME、TRUNCATE、OPTIMIZE操作のみをサポートします。この機能は、プライマリノードからのデータ同期中、セカンダリノードまたは読み取り専用インスタンスでは有効になりません。
/*+ WAIT(n) */で MDL 待ち時間を設定する場合、n (待ち時間) の値は [0, 31536000] の範囲内である必要があります。単位は秒です。
使用方法
CREATE、DROP、ALTER、RENAME、TRUNCATE、OPTIMIZE 操作を実行する際に、キーワードの後に /*+ WAIT(n) */ または /*+ NO_WAIT() */ を追加して、MDL ロック待ち時間を制御します。以下の例は、ヒントの使用方法を示しています:
-- テーブル t1 を作成し、MDL タイムアウトを 10 秒に設定します。
CREATE /*+ WAIT(10) */ TABLE t1(a INT);
-- テーブル t1 に列を追加し、MDL タイムアウトを待機なしに設定します。
ALTER /*+ NO_WAIT() */ TABLE t1 ADD COLUMN b INT;
-- テーブル t1 を削除し、MDL タイムアウトを 1 秒に設定します。
DROP /*+ WAIT(1) */ TABLE t1;結果
テスト方法
セッションを開始します。
t1という名前のテーブルを作成し、そのテーブルに対して MDL S ロックを保持します。CREATE TABLE t1(a INT); LOCK TABLE t1 READ;別のセッションを開始します。
/*+ WAIT(n) */と/*+ NO_WAIT() */を使用してスキーマ変更と削除操作を実行し、ステートメントの実行を観察します。ALTER /*+ NO_WAIT() */ TABLE t1 ADD COLUMN b INT; DROP /*+ WAIT(1) */ TABLE t1;
テスト結果
/*+ WAIT(n) */ と /*+ NO_WAIT() */ を使用して MDL タイムアウトを制御した後、スキーマ変更と削除操作は期待された時間内に失敗します。
mysql> ALTER /*+ NO_WAIT() */ TABLE t1 ADD COLUMN b INT;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> DROP /*+ WAIT(1) */ TABLE t1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction