メタデータロック (MDL) は、DDLステートメントの実行中にトランザクションによって使用されるテーブルメタデータの一貫性を確保するために使用されるデータベースの内部ロックです。 一般的な読み書きトランザクションの場合、対応するテーブルの読み取りMDLを取得する必要があります。 DDL操作の場合、対応するテーブルの書き込みMDLを取得する必要があります。 DDLステートメントの実行中は、MDLに関連する次の問題に注意する必要があります。
リスクをブロックする
実行時間の長いトランザクションによって保持されている読み取りMDLは、DDLステートメントの実行をブロックします。 これは、書き込みMDLに対する不成功の長時間要求によるDDL障害につながる。 さらに、MySQLのMDLはフェアロックです。 したがって、読み取りMDLが書き込みMDLを待機するために実行時間の長いトランザクションによって保持されているためにDDLステートメントがブロックされた場合、新しいトランザクションも読み取りMDLをキューに入れているときにブロックされます。
デッドロックのリスク
複数のDDLステートメントとトランザクションが同時に実行される場合、MDLが要求される順序が異なるため、メタデータのデッドロックが発生する可能性があります。
除外リスク
書き込みMDLは排他的です。 DDL文の書き込みMDLが取得された後、すべての新しいトランザクションは読み取りMDLを要求できないため待機します。 この結果、トラフィックはゼロに低下する。 オンラインDDL機能はMySQLでサポートされていますが、このようなDDLステートメントは、プロセス全体で可能な限りテーブルロックを防止するだけです。 いくつかの重要なステップでは、短期書き込みMDL取得が必要です。
DDL文の実行中に上記の問題が発生すると、サービス接続が蓄積されてブロックされる可能性があります。 深刻なケースでは、一時的なサービストラフィックのゼロへのドロップが発生し、深刻な結果になります。 PolarDB-Xは、前述のMDL関連の問題に対する最適化を提供し、DDLステートメントの実行中の前述のリスクを排除します。
プリエンプティブルMDL最適化
PolarDB-Xは、プリエンプティブルMDL最適化をサポートしています。これにより、DDLステートメントの実行中のMDLのブロックによる潜在的なリスクが排除されます。
サポートされているバージョン
この機能は、PolarDB-X V5.4.17-16952556以降でのみサポートされます。
説明
MDLの書き込みが必要なDDLステートメントの実行中に、MDLの書き込み待機時間がしきい値を超えると、PolarDB-Xは、このDDLステートメントの実行時間の長いトランザクションが属する接続のブロックを自動的に停止します。
次の表は、プリエンプティブルMDL最適化が利用できない場合に、DDLステートメントと新しいトランザクションが以前の長期トランザクションによってブロックされるシナリオを示しています。
表1
ステップ | セッション1 | セッション2 | セッション3 |
1 | 始める; | - | 始める; |
2 | tb0値 (1) に挿入する。 -- tb0の読み取りMDLを取得します。 | - | - |
3 | -トランザクションを長期間コミットしないようにして、実行時間の長いトランザクションをシミュレートします。 | - | - |
4 | - | テーブルを変更tb0列col intを追加します。 -- tb0の書き込みMDLの取得を試みます。 このステートメントは、実行時間の長いトランザクションによってブロックされます。 | - |
5 | - | - | tb0からidを選択します。 -- tb0の書き込みMDLの取得を試みます。 このステートメントはブロックされます。 |
次の図は、プリエンプティブルMDL最適化を有効にした後の実行プロセスを示しています。 ステップは表1に記載されたものと同じであり、重要なステップは次の図でマークされています。
前の図に示すように、セッション1の実行時間の長いトランザクションが属する接続は、プリエンプティブルMDL最適化のために閉じられます。 これにより、セッション2のDDLステートメントとセッション3の新しいトランザクションを実行できるようになります。
分散メタデータのデッドロック検出
PolarDB-Xは、分散メタデータのデッドロック検出をサポートします。 この機能は、DDLステートメントの実行中にMDLによって引き起こされるデッドロックを検出して解除できます。 これにより、DDL文とトランザクションを適切に実行できます。
サポートされているバージョン
この機能は、PolarDB-X V5.4.17-16952556以降でのみサポートされます。
説明
PolarDB-Xは、トランザクションとDDLステートメント間のロック待機を定期的にスキャンします。 デッドロックが検出された場合、PolarDB-Xは共通トランザクションを自動的に停止し、DDLステートメントおよびその他のトランザクションの正常な実行を保証します。
次の表は、MDLが関与する一般的なデッドロックシナリオを示しています。
表2
ステップ | セッション1 | セッション2 | セッション3 | セッション4 |
1 | 始める; -- トランザクション1を開始します。 | 始める; -- トランザクション2を開始します。 | - | - |
2 | t1値 (1) に挿入する。 -- t1の読み取りMDLを取得します。 | t2値 (1) に挿入する。 -- t2の読み取りMDLを取得する。 | - | - |
3 | - | - | テーブルを変更t1列col intを追加します。 -- DDLステートメント1を開始し、t1の書き込みMDLの取得を試みます。 このステートメントはブロックされます。 | テーブルt2を変更列col intを追加します。 -- DDLステートメント2を開始し、t2の書き込みMDLの取得を試みます。 このステートメントはブロックされます。 |
4 | t2値 (2) に挿入する。 -- t2の読み取りMDLの取得を試みます。 ただし、MDLは公正なロックであるため、このステートメントはDDLステートメント2によってブロックされます。 | t1値 (2) に挿入する。 -- t1の読み取りMDLの取得を試みます。 ただし、MDLは公正なロックであるため、このステートメントはDDLステートメント1によってブロックされます。 | - | - |
次の図は、分散メタデータのデッドロック検出機能が有効になっているPolarDB-Xインスタンスで、表2に示すデッドロック問題がどのように解決されるかを示しています。 ステップは表2に記載されたものと同じであり、キーステップは次の図でマークされています。
デッドロックシナリオが表2で指定されたシーケンスで生成された後、PolarDB-Xはデッドロックを検出し、トランザクション2が属する接続を閉じます。 トランザクション2がロールバックされ、トランザクション1、DDLステートメント1、およびDDLステートメント2が実行される。
デュアルバージョンMDL最適化
論理的に実行されるDDL文の場合、PolarDB-Xはデュアルバージョンメタデータと対応するデュアルバージョンMDLをサポートします。 これにより、テーブルがロックされず、そのようなDDLステートメントの実行中にトラフィックがゼロに落ちないことが保証されます。
制限事項
この機能は、PolarDB-Xで論理的に実行されるすべてのDDLステートメントでサポートされます。 DDLステートメントが論理的に実行されているかどうかを確認する方法の詳細については、「Online DDL」をご参照ください。
説明
PolarDB-XでのDDLステートメントの論理実行は、オンラインスキーマ変更 (OSC) 機能に基づいて実装されます。 このようなDDLステートメントのメタデータバージョンは、複数のマイナーバージョンに分割されます。 これにより、メタデータバージョンをPolarDB-Xインスタンスで安全に進化させることができます。 たとえば、ABSENT(Vn) 、DELETE_ONLY(Vn + 1) 、WRITE_ONLY(Vn + 2) 、およびPUBLISH(Vn + 3) の複数回のバージョン切り替えは、PolarDB-XでCREATE GLOBAL INDEX
ステートメントを実行するプロセス全体に含まれます。 さらに、PolarDB-XはMDLをメタデータのマイナーバージョンに関連付けます。 このように、各バージョンのメタデータは、別個のMDLを有する。
OSCメカニズムに基づいて、2つのメタデータバージョンは、クラスタ内の異なる計算ノード (CN) 間だけでなく、特定の時点で1つのCN内でも許可されます。 したがって、論理的に実行されたDDL文に対してメタデータバージョンが進化するたびに、PolarDB-Xは以前のバージョンのメタデータのみに対応するMDL書き込みロックを取得します。 この場合、新しいトランザクションは、新しいバージョンのメタデータにアクセスし、新しいバージョンのメタデータに対応する読み取りMDLを要求することができる。
デュアルバージョンMDL最適化に基づいて、PolarDB-Xは、テーブルがロックされず、論理的に実行されたDDLステートメントの実行中にトラフィックがゼロにならないようにします。