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

PolarDB:読み取り専用ノード上の長時間トランザクションが DDL 操作をブロックするのを防止

最終更新日:Mar 29, 2026

読み取り専用ノード上で実行中の長時間トランザクションがテーブルのメタデータロック (MDL) を保持している場合、プライマリノードでのデータ定義言語 (DDL) 操作は、そのトランザクションが終了するか、replica_lock_wait_timeout(デフォルト:50 秒)がタイムアウトするまでブロックされます。タイムアウトが発生すると、DDL 操作は ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize エラーで失敗します。

polar_slave_work_on_nonblock_mdl_modeON に設定すると、プライマリノードでの DDL 操作が、読み取り専用ノード上で競合する MDL の解放を待たずに続行されるようになります。

仕組み

PolarDB for MySQL クラスターでは、プライマリノードでの DDL 操作が完了する前に、すべての読み取り専用ノードに対して MDL の同期を行う必要があります。読み取り専用ノード上で実行中の長時間トランザクションが対象テーブルの MDL を保持している場合、そのトランザクションが終了するか replica_lock_wait_timeout がタイムアウトするまで、MDL 同期はブロックされます。

polar_slave_work_on_nonblock_mdl_modeON の場合、プライマリノードでの DDL 操作は、読み取り専用ノード上の競合する MDL を待たずに即座に続行されます。ただし、この設定により、プライマリノードで同時実行された DDL 操作によって、読み取り専用ノード上の単一トランザクション内で異なるテーブルスキーマが観測される可能性があります。

このパラメーターは、長時間トランザクションが原因で発生する MDL ブロッキングのみを解消します。LOCK TABLES または FLUSH TABLES によるブロッキングは解消されません。これらの MDL は、明示的に UNLOCK TABLES を実行して解放する必要があります。

前提条件

このパラメーターを有効化する前に、クラスターが以下のすべての条件を満たしていることを確認してください。

バージョン要件 — クラスターは以下のいずれかを満たしている必要があります。

  • PolarDB for MySQL 8.0、リビジョンバージョン 8.0.1.1.23 以降

  • PolarDB for MySQL 5.7、リビジョンバージョン 5.7.1.0.19 以降

  • PolarDB for MySQL 5.6、リビジョンバージョン 5.6.1.0.32 以降

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

分離レベル要件 — 読み取り専用ノードのトランザクション分離レベルは Read Committed または Read Uncommitted である必要があります。Repeatable Read または Serializable 分離レベルでは、このパラメーターは効果がありません。

MDL ブロッキングの診断

パラメーターを有効化する前に、ブロッキングの根本原因が長時間トランザクション(LOCK TABLESFLUSH TABLES ではない)であることを確認してください。このパラメーターは、明示的なテーブルロックによって保持されている MDL を解除できません。

ステップ 1:プライマリノードでSHOW PROCESSLIST を実行し、State = Wait for syncing with replicas と表示されている行があるかどうかを確認します。該当する行が存在する場合、DDL 操作が読み取り専用ノードでの MDL 同期待ち状態でブロックされています。

SHOW PROCESSLIST;

ステップ 2:読み取り専用ノードで — ブロッキングを引き起こしているトランザクションを特定します。

SELECT * FROM information_schema.innodb_log_mdl_slot WHERE slot_state = 'SLOT_ACQUIRING';

クエリが行を返す場合、長時間トランザクションが MDL を保持しています。

+---------+----------------+-----------+----------+-----------+
| slot_id | slot_state     | slot_name | slot_lsn | thread_id |
+---------+----------------+-----------+----------+-----------+
|       0 | SLOT_ACQUIRING | test/t    | 35025648 | thread-0  |
+---------+----------------+-----------+----------+-----------+

出力結果に基づく次のステップ:

状況対応
クエリが行を返す(長時間トランザクションが確認された)polar_slave_work_on_nonblock_mdl_mode を有効化して、今後の発生を防止してください。現在ブロックされている DDL を即座に解除するには、出力結果の thread_id を使用して、該当トランザクションを終了します。
クエリが行を返さないブロッキングは長時間トランザクションが原因ではありません。LOCK TABLES または FLUSH TABLES 文がアクティブで実行されていないか確認し、UNLOCK TABLES でロックを解放してください。

パラメーターの有効化

  1. PolarDB コンソール にログインします。

  2. 左上隅で、ご利用のクラスターがデプロイされているリージョンを選択します。

  3. クラスターを見つけ、その ID をクリックします。

  4. 左側のナビゲーションウィンドウで、設定と管理 > パラメーター を選択します。

  5. loose_polar_slave_work_on_nonblock_mdl_mode を見つけ、パラメーターの変更 をクリックします。

    参数配置

  6. 変更の送信 をクリックします。変更の保存 ダイアログボックスで、OK をクリックします。

    保存改动

制限事項と副作用

カテゴリ詳細
適用範囲読み取り専用ノードにのみ適用されます。プライマリノードには影響しません。
テーブルロック/フラッシュLOCK TABLES または FLUSH TABLES によって保持されている MDL はバイパスできません。これらのロックは UNLOCK TABLES で解放してください。
並列クエリのタイムアウトこのパラメーターを有効化した後も、読み取り専用ノード上の並列クエリが replica_lock_wait_timeout(デフォルト:50 秒)を超えて実行されると、MDL 同期の失敗が発生する可能性があります。
スキーマの一貫性このパラメーターが ON の場合、プライマリノードで同時実行された DDL 操作により、読み取り専用ノード上のトランザクション内で異なるテーブルスキーマが観測される可能性があります。例については、以下のセクションをご参照ください。

パラメーターが ON の場合のスキーマ一貫性の動作

polar_slave_work_on_nonblock_mdl_modeON の場合、プライマリノードでの DDL 操作は、読み取り専用ノード上で実行中のトランザクションを待たなくなります。その結果、読み取り専用ノード上の単一トランザクション内で、2 種類のテーブルスキーマが観測されることがあります。

読み取り専用ノード(セッション 1)プライマリノード(セッション 2)
BEGIN;
SELECT * FROM test.t; — カラム a のみを返す
ALTER TABLE test.t ADD COLUMN b INT; — 即座に成功
SELECT * FROM test.t; — カラム a および b
COMMIT;

セッション 1 の 2 回目の SELECT は更新後のスキーマを返します。これは、セッション 2 の DDL がトランザクションがまだ開いている間に完了したためです。

このパラメーターが OFF(デフォルト)の場合、セッション 2 の DDL はセッション 1 がコミットするか replica_lock_wait_timeout がタイムアウトするまでブロックされ、ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize エラーが返されます。

お問い合わせ

DDL 操作についてご質問がある場合は、テクニカルサポートまでお問い合わせください。