PolarDB-Xは2相DDL機能をサポートしています。 この機能を使用すると、一部のシャードではユーザーDDLステートメントの物理的な実行が成功し、他のシャードでは失敗することを防ぐことができます。 これにより、物理DDLステートメントのアトミック性の問題が効果的に解決されます。 このトピックでは、論理的に実行されるDDLステートメントにアトミック性の問題がないため、物理的に実行されるDDLステートメントのアトミック性について説明します。
背景情報
PolarDB-Xでは、論理テーブルは複数の物理テーブルに対応します。これはシャードとも呼ばれます。 これらのシャードは、複数のデータノード (DN) に分散されます。 DDLステートメントが論理テーブルで物理的に実行される場合、関連する物理DDLステートメントは、論理テーブルに対応するすべてのシャードで実行する必要があります。 物理DDLステートメントは、シャードに対して個別に実行されます。 その結果、ほとんどの場合、物理的実行の原子性を保証することができない。 DDLステートメントが論理的に実行された場合、計算ノード (CN) は一時テーブルを作成し、履歴データをインポートし、増分データを二重書き込みモードで同期してから、テーブルメタデータを切り替えます。 加えて、テーブルメタデータを切り替えるプロセスは、アトミックである。 したがって、論理実行のアトミック性の問題は存在しません。
物理DDLステートメントのアトミック性がサポートされていない場合、物理DDLステートメントは、一貫したコミット時点なしに複数のシャードで個別に実行されます。 CNおよびDNは、メタデータ情報を別々に格納する。 ある時点で、コンピューティングレイヤのメタデータビューと、ストレージレイヤの複数のシャードのメタデータビューとが異なる場合があり、その結果、クエリエラーが発生する可能性があります。
さらに、ALTER TABLE modify COLUMNなど、列のスキーマ制約を変更するステートメントの場合、シャード上の既存のデータが制約に違反する可能性があるため、物理DDLステートメントは失敗する可能性があります。 物理DDLステートメントの実行が一部のシャードで成功し、他のシャードで失敗した場合、コンピューティングレイヤーは、物理DDLステートメントを配信することによって一貫したロールバックセマンティクスを実装できません。 この場合、手動による介入が必要になり、メタデータビューが長期間一貫しなくなる可能性があり、ビジネスに影響を与える可能性があります。
PolarDB-Xでサポートされている2フェーズDDL機能は、複数のシャードで物理DDLステートメントをコミットするためのバリアをDNに構築することで、コミットポイントの前に物理DDLステートメントのロールバックとコミット動作を制御できます。 これにより、DDLステートメントが複数のシャードでアトミックにコミットされ、シャードで一貫したメタデータビューが提供されます。
使用上の注意
2フェーズDDL機能をサポートしているのは、カーネルバージョンが5.4.18-17108394以降のPolarDB-Xインスタンスのみです。
関係するすべてのシャードを接続し、スレッドを実行し続ける必要があります。 1つのDNに500を超えるシャードを持つ大規模な論理テーブルはサポートされていません。
COPYタイプの物理DDLステートメントの場合、分散DDLステートメントの影響は、シャードのロックから論理テーブル全体のロックに変わります。
物理DDLステートメントは、コミットフェーズでデータディクショナリを変更します。 この操作はグローバルで相互に排他的な操作です。 2相DDL機能では、テーブルがロックされたときに操作が実行されます。
ビジネスがテーブルロックに敏感な場合は、オンライン列の変更 (OMC) 機能を使用することをお勧めします。 この機能により、テーブルをロックすることなく列の種類を変更できます。 OMC操作は論理的に実行され、アトミック性を保証できます。 詳細については、「列の種類をオンラインで変更する」をご参照ください。
適用範囲
2フェーズDDL機能は、ADD COLUMN、DROP COLUMN、ADD INDEX、DROP INDEX、およびMODIFY COLUMNの物理DDLステートメントにのみ適用されます。
この機能は、物理パーティション、外部キー、またはフルテキストインデックスを含むテーブルには適用されません。
使用法
インスタンスが2フェーズDDL機能をサポートしているかどうか、およびこの機能が有効になっているかどうかを確認します。
show変数のような "enable_two_phase_ddl";結果が返されない場合、2フェーズDDL機能はサポートされません。 trueが返された場合、2フェーズDDL機能が有効になります。 falseが返された場合、2相DDL機能は無効になります。
-- 2相DDL機能はデフォルトで有効になっています。 "enable_two_phase_ddl" のような変数を表示します。+ ---------------------- + ------- | Variable_name | 値 | + ---------------------- + ------- | enable_two_phase_ddl | ON | + ---------------------- + -------2フェーズDDL機能を有効にします。
グローバルenable_two_phase_ddl = trueを設定します。2フェーズDDL機能を無効にします。
設定グローバルenable_two_phase_ddl = false;
例
PolarDB-Xインスタンスで、t1という名前の論理テーブルを作成します。 次のサンプルコードは、そのスキーマを示しています。
+ ------- + -------------------------------------------------------------------------- + | テーブル | テーブルの作成 | + ------- + -------------------------------------------------------------------------- + | t1 | CREATE TABLE 't1' ( 'a' int(11) DEFAULT NULL、 'b' int (11) DEFAULT NULL ) エンジン=InnoDBデフォルト料金=utf8mb4 キーによるパーティー ('a') パーティー16 | + ------- + -------------------------------------------------------------------------- +論理テーブルt1にデータを書き込む。
t1に値 (1,1) 、(2,2) 、(3,3) 、(4,4) 、(5,999999) を挿入します。クエリOK、影響を受ける1行 (0.01秒)strictモードで、
ALTER TABLE t1 MODIFY COLUMN b tinyintステートメントを実行します。 t1テーブルは、b列の値が999999であるレコードを含む。 strictモードでは、このレコードが存在するシャードで物理DDLステートメントが失敗することが予想されます。 2相DDL機能がデフォルトで有効になっているため、変更はすべてのシャードで失敗すると予想されます。ALTER TABLE t1 MODIFY COLUMN b tinyint; エラー4700 (HY000): ERR-CODE: [TDDL-4700][ERR_SERVER] サーバーエラーby DDLタスクの実行に失敗しました。 原因: ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] ERR-CODE: [ERR_DDL_JOB_ERROR] がグループで実行できませんでした (WUMU_P00000_GROUP): /* drds_two_phase_ddl(1717761420461916160)*/ALTER value 't1_KdRs_00004 COLUMNデータ: FintY \rangeの切り捨て .SHOW DDLおよびSHOW DDL RESULTステートメントを実行して、現在のインスタンスのDDLタスクと過去の実行結果を表示します。ショーddl; 空セット (0.01秒) ショーのddlの結果; + --------------------- + ------------------------------------------------------------------ + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + | JOB_ID | SCHEMA_NAME | OBJECT_NAME | DDL_TYPE | RESULT_TYPE | RESULT_CONTENT | + --------------------- + ------------------------------------------------------------------ + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + | 1717761420575162368 | wumu | t1 | ALTER_TABLE | ERROR | DDLタスクの実行に失敗しました。 原因: ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] ERR-CODE: [ERR_DDL_JOB_ERROR] がグループで実行できませんでした (WUMU_P00000_GROUP): /* drds_two_phase_ddl(1717761420461916160)*/ALTER value 't1_KdRs_00004 COLUMNデータ: FintY \rangeの切り捨て . | + --------------------- + ------------------------------------------------------------------ + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + セットで1行 (0.03秒)CHECK TABLEステートメントを実行して、論理テーブルのシャードのスキーマが同じかどうか、およびメタデータが計算レイヤーのものと同じかどうかを確認します。チェックテーブルt1; + --------------------------------- + ------------------------------ + | テーブル | OP | MSG_TYPE | MSG_TEXT | + --------------------------------- + ------------------------------ + | wumu.t1: トポロジ | チェック | ステータス | OK | | wumu.t1: 列 | チェック | ステータス | OK | | t1.auto_shard_key_a: ローカルインデックス | チェック | ステータス | OK | + --------------------------------- + ------------------------------ + セットの3列 (0.01秒) ショー作成テーブルt1; + ------- + ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + | テーブル | テーブルの作成 | + ------- + ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + | t1 | CREATE TABLE 't1' ( 'a' int(11) DEFAULT NULL、 'b' int(11) DEFAULT NULL、 キー 'auto_shard_key_a '使用してBTREE ('a') ) エンジン=InnoDBデフォルト料金=utf8mb4 キーによるパーティー ('a') パーティー16 | + ------- + ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + 1行セット (0.01秒)