すべてのプロダクト
Search
ドキュメントセンター

PolarDB:プリエンプティブ DDL

最終更新日:Jun 22, 2026

PolarDB for MySQL は、読み取り専用ノードのテーブルに対する大規模なクエリや長時間実行されるトランザクションが原因でデータ定義言語 (DDL) 操作が失敗するのを防ぐためのプリエンプティブ DDL 機能を提供します。

症状

PolarDB for MySQL データベースで DDL 操作を実行すると、メタデータロック (MDL) を取得できないことを示すエラーが発生します。 次のエラーメッセージが表示されます。

ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize
ERROR HY000: Fail to get table lock on replica; you can 'set polar_support_mdl_sync_preemption = ON' and try restarting transaction

前提条件

お使いのPolarDB for MySQL クラスターは、以下のいずれかのリビジョンを使用する必要があります:

  • PolarDB for MySQL 5.6:リビジョン 5.6.1.0.43 以降。

  • PolarDB for MySQL 5.7:リビジョン 5.7.1.0.34 以降。

  • PolarDB for MySQL 8.0.1:リビジョン 8.0.1.1.39 以降。

  • PolarDB for MySQL 8.0.2:リビジョン 8.0.2.2.14 以降。

クラスターのリビジョンを確認するには、クラスターのバージョンの確認をご参照ください。

制限事項

プリエンプティブ DDL 機能は、読み取り専用ノードでのみサポートされ、プライマリノードではサポートされていません。

使用上の注意

  • プリエンプティブ DDL を有効にすると、読み取り専用ノードで対象テーブルにアクセスしている接続が切断されたり、そのテーブルで実行中の SQL クエリがロールバックされたりする可能性があります。この機能は慎重に使用してください。

  • プリエンプティブ DDL 機能が有効になるのは、loose_replica_lock_wait_timeout パラメーターの値が loose_polar_mdl_sync_preempt_after_wait_second パラメーターの値に 5 を加えた値よりも大きい場合のみです。

  • PolarDB for MySQL 8.0.1 および PolarDB for MySQL 8.0.2 では、この機能は名前変更操作をサポートしていません。 代わりに ALTER TABLE ... RENAME ステートメントを使用することを推奨します。

背景

PolarDB for MySQL は共有ストレージアーキテクチャを使用します。DDL 操作を実行すると、プライマリノードはまず排他的メタデータ (MDL-X) ロックを取得し、次にすべての読み取り専用ノードに同じロックを取得するように指示します。読み取り専用ノードでトランザクションが対象のテーブルにアクセスしている場合、MDL ロック同期プロセスはブロックされます。読み取り専用ノードが指定されたタイムアウト期間内に MDL-X ロックを取得できない場合、クライアントは ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize エラーを返します。この問題は、複数の読み取り専用ノードを持つ PolarDB for MySQL クラスターでよく発生します。プリエンプティブ DDL 機能は、この問題に対処するために設計されています。

手順

プリエンプティブ DDL 機能は loose_polar_support_mdl_sync_preemption パラメーターで有効にでき、プリエンプション待機タイムアウトは loose_polar_mdl_sync_preempt_after_wait_second パラメーターで設定できます。詳細については、「クラスターおよびノードパラメーターの指定」をご参照ください。次の表では、これらのパラメーターについて説明します。

パラメーター

レベル

説明

loose_polar_support_mdl_sync_preemption

セッション

プリエンプティブ DDL 機能を制御します。有効な値:

  • ON:プリエンプティブ DDL 機能を有効にします。

  • OFF (デフォルト):プリエンプティブ DDL 機能を無効にします。

loose_polar_mdl_sync_preempt_after_wait_second

グローバル

MDL ロック同期がブロックされた場合の待機タイムアウトを秒単位で指定します。この期間が経過してもロックが取得されない場合、システムはブロッキングスレッドをプリエンプトします。

有効な値:1~31536000。単位:秒。デフォルト値:10。

プリエンプティブ DDL 無効

  1. 読み取り専用ノードで、test.t1 テーブルに対してクエリを実行します。

    mysql> use test;
    Database changed
    # 100 秒間実行される大規模なクエリ
    mysql> select sleep(100) from t1;
  2. プライマリノードで、テーブルに列を追加します。

    mysql> alter table t1 add column c int;
    ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize

    この例は、プリエンプティブ DDL 機能が無効な場合、DDL 操作がブロックされ、最終的に失敗することを示しています。これは、読み取り専用ノードでの長時間実行トランザクションが MDL ロック同期を妨げているためです。

    mysql> select sleep(100) from t1;
    +------------+
    | sleep(100) |
    +------------+
    |          0 |
    +------------+
    1 row in set (1 min 40.00 sec)

プリエンプティブ DDL 有効

  1. 読み取り専用ノードで、test.t1 テーブルに対してクエリを実行します。

    mysql> use test;
    Database changed
    # 100 秒間実行される大規模なクエリ
    mysql> select sleep(100) from t1;
  2. プライマリノードで、テーブルに列を追加します。

    mysql> alter table t1 add column c int;
    Query OK, 0 rows affected (11.13 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    この例は、プリエンプティブ DDL 機能が有効な場合、MDL ロック同期は最初は長時間実行トランザクションによってブロックされますが、待機期間の後、機能がブロッキングスレッドをプリエンプトし、DDL 操作が成功することを示しています。

    mysql> select sleep(100) from t1;
    ERROR 2013 (HY000): Lost connection to MySQL server during query

お問い合わせ

DDL 操作についてご不明な点がございましたら、テクニカルサポートにお問い合わせください。