PolarDB-X 1.0 では、データ定義言語(DDL)ジョブの管理を目的とした拡張 SQL ステートメントが提供されています。これらのステートメントを使用して、実行中の DDL ジョブをモニターしたり、失敗から回復したり、停止したジョブをクリーンアップしたりできます。
| ステートメント | 目的 |
|---|---|
SHOW [FULL] DDL | 実行中および保留中の DDL ジョブを確認します |
RECOVER DDL | PENDING 状態で停止したジョブを再開します |
ROLLBACK DDL | PENDING 状態の CREATE TABLE または RENAME TABLE ジョブをロールバックします |
CANCEL DDL | 実行中のジョブをキャンセルし、PENDING 状態に移行させます |
REMOVE DDL | 保留中のジョブを削除し、内部キャッシュをクリアします |
ジョブの照会
SHOW DDL は、DDL キュー内にあるすべての DDL ジョブ(実行中のジョブおよび失敗により PENDING 状態となったジョブ)を返します。正常に完了したジョブは COMPLETED 状態となり、自動的にクリアされるため、出力には表示されません。
構文
SHOW [FULL] DDLパラメーター
| パラメーター | 説明 |
|---|---|
FULL | すべてのフィールドを返します。FULL を指定しない場合、出力には JOB_ID、OBJECT_SCHEMA、OBJECT_NAME、JOB_TYPE、PHASE、STATE、PROGRESS、START_TIME、END_TIME、ELAPSED_TIME、REMARK、PHY_PROCESS、BACKFILL_PROGRESS のみが含まれます。 |
出力フィールド
| フィールド | 説明 |
|---|---|
JOB_ID | DDL ジョブの固有 ID。64 ビット符号付き整数です。 |
PARENT_JOB_ID | 親 DDL ジョブの ID。親ジョブが存在しない場合は 0 に設定されます。64 ビット符号付き整数です。 |
SERVER | DDL ジョブを実行している DRDS サーバーノードです。 |
OBJECT_SCHEMA | オブジェクトのスキーマ名(例:データベース名)です。 |
OBJECT_NAME | オブジェクトの名前(例:テーブル名)です。 |
NEW_OBJECT_NAME | RENAME TABLE 操作の対象テーブル名です。その他のジョブタイプでは空になります。 |
JOB_TYPE | DDL 操作の種類(例:CREATE_TABLE、DROP_TABLE)です。 |
PHASE | ジョブの現在の実行フェーズ(例:EXECUTE)です。 |
STATE | ジョブの現在の状態です。有効な値は以下のとおりです:RUNNING(通常実行中)、PENDING(中断または失敗)、COMPLETED(完了済みで自動クリア済み)。 |
PROGRESS | ジョブの完了率(パーセント)です。 |
START_TIME | 実行開始時のタイムスタンプです。 |
END_TIME | 実行終了時のタイムスタンプです。 |
ELAPSED_TIME | 実行終了後からの経過時間(ミリ秒単位)です。 |
DDL_STMT | 元の DDL ステートメントです。 |
REMARK | PENDING ジョブの場合、失敗原因が記載されます。実行中のジョブでは空になります。 |
例
この例では、シャード化されたテーブルを作成し、その実行中にジョブを照会します。CREATE TABLE ステートメントを 1 つの接続で実行し、SHOW FULL DDL を別の接続で実行します。
接続 1 で、以下を実行します。
mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64;接続 2 で、ジョブを照会します。
mysql> show full ddl\G *************************** 1. row *************************** JOB_ID: 1103792075578957824 PARENT_JOB_ID: 0 SERVER: 1:102:10.81.69.55 OBJECT_SCHEMA: ddltest OBJECT_NAME: test_mdb_mtb NEW_OBJECT_NAME: JOB_TYPE: CREATE_TABLE PHASE: EXECUTE STATE: RUNNING PROGRESS: 90% START_TIME: 2019-08-29 14:29:58.787 END_TIME: 2019-08-29 14:30:07.177 ELAPSED_TIME(MS): 8416 DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64 REMARK:STATEはRUNNING、PROGRESSは 90 % であり、ジョブがまだ実行中であることを示しています。REMARKフィールドが空であることは、エラーが発生していないことを確認します。ジョブが完了すると、COMPLETED 状態に移行し、キューから自動的に削除されます。
ジョブの再開
RECOVER DDL は、PENDING 状態の DDL ジョブを 1 つ以上再開します。
再開する前に、SHOW DDL を実行し、REMARK フィールドを確認して、ジョブが失敗した原因を特定してください。まず根本的な問題を解決してください。原因を解決せずに再開すると、ジョブは直ちに再度失敗します。
構文
RECOVER DDL { ALL | <job_id> [, <job_id>] ... }パラメーター
| パラメーター | 説明 |
|---|---|
ALL | すべての PENDING ジョブを再開します。このモードでは、ジョブはシリアルに実行されます。本番環境では注意して使用してください。 |
job_id | 再開する PENDING ジョブの ID です。JOB_ID フィールドの値は、SHOW DDL の出力から取得します。 |
例
この例では、CREATE TABLE ジョブの実行途中で中断し、その後再開します。
接続 1 で、シャード化されたテーブルの作成を開始し、中断します。
mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64; ^C^C -- クエリが中止されましたジョブを照会し、PENDING 状態であることを確認して、
JOB_IDを取得します。mysql> show ddl\G *************************** 1. row *************************** JOB_ID: 1103796219480006656 OBJECT_SCHEMA: ddltest OBJECT_NAME: test_mdb_mtb JOB_TYPE: CREATE_TABLE PHASE: EXECUTE STATE: PENDING PROGRESS: 33% START_TIME: 2019-08-29 14:46:26.769 END_TIME: 2019-08-29 14:46:29.691 ELAPSED_TIME(MS): 2922 DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64 REMARK: The job has been interrupted unexpectedlySTATEはPENDINGであり、REMARKには「ジョブが予期せず中断されました」と記載されています。これはデータ整合性の問題ではなく、安全に再開できます。ジョブを再開します。
mysql> recover ddl 1103796219480006656; Query OK, 0 rows affected (7.28 sec)CHECK TABLEを実行し、テーブルが不整合なく作成されたことを確認します。mysql> check table test_mdb_mtb; +----------------------------------------+-------+----------+----------+ | TABLE | OP | MSG_TYPE | MSG_TEXT | +----------------------------------------+-------+----------+----------+ | ddltest_1562056402230oymk.test_mdb_mtb | check | status | OK | +----------------------------------------+-------+----------+----------+ 1 row in set (2.24 sec)status: OKの結果は、テーブルが整合性を保っていることを確認します。
ジョブのロールバック
ROLLBACK DDL は、PENDING 状態の DDL ジョブをロールバックし、失敗前に部分的に適用された変更を元に戻します。
ロールバックは、CREATE TABLE および RENAME TABLE ジョブのみサポートされます。その他の DDL ジョブタイプについては、同じオブジェクトに対する追加の DDL 操作を実行する前に、まず PENDING ジョブを再開してください。
構文
ROLLBACK DDL <job_id> [, <job_id>] ...パラメーター
| パラメーター | 説明 |
|---|---|
job_id | ロールバックする PENDING ジョブの ID です。JOB_ID フィールドの値は、SHOW DDL の出力から取得します。 |
例
この例では、CREATE TABLE ジョブを中断し、ロールバックします。
接続 1 で、シャード化されたテーブルの作成を開始し、中断します。
mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64;ジョブを照会し、
JOB_IDを取得します。mysql> show ddl\G *************************** 1. row *************************** JOB_ID: 1103797850607083520 OBJECT_SCHEMA: ddltest OBJECT_NAME: test_mdb_mtb JOB_TYPE: CREATE_TABLE PHASE: EXECUTE STATE: PENDING PROGRESS: 40% START_TIME: 2019-08-29 14:52:55.660 END_TIME: 2019-08-29 14:52:58.885 ELAPSED_TIME(MS): 3225 DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64 REMARK: The job has been interrupted unexpectedlyジョブをロールバックします。
mysql> rollback ddl 1103797850607083520; Query OK, 0 rows affected (6.42 sec)テーブルが存在しないことを確認します。
mysql> show tables like 'test_mdb_mtb'; Empty set (0.00 sec)空の結果セットは、ロールバックが成功し、テーブルが削除されたことを確認します。
ジョブのキャンセル
CANCEL DDL は、実行中の DDL ジョブ(PENDING 状態ではないジョブ)をキャンセルします。キャンセル後、ジョブは REMARK フィールドにエラーを含む PENDING 状態に移行します。PENDING 状態になった後は、RECOVER DDL でジョブを再開するか、ROLLBACK DDL でロールバックできます。
構文
CANCEL DDL <job_id> [, <job_id>] ...パラメーター
| パラメーター | 説明 |
|---|---|
job_id | キャンセルする実行中の DDL ジョブの ID です。JOB_ID フィールドの値は、SHOW DDL の出力から取得します。 |
例
この例では、実行中の CREATE TABLE ジョブをキャンセルします。
接続 1 で、シャード化されたテーブルの作成を開始します。
mysql> create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64;接続 2 で、実行中のジョブを照会し、
JOB_IDを取得します。mysql> show ddl\G *************************** 1. row *************************** JOB_ID: 1103798959568478208 OBJECT_SCHEMA: ddltest OBJECT_NAME: test_mdb_mtb JOB_TYPE: CREATE_TABLE PHASE: EXECUTE STATE: RUNNING PROGRESS: 26% START_TIME: 2019-08-29 14:57:20.058 END_TIME: 2019-08-29 14:57:22.284 ELAPSED_TIME(MS): 2243 DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64 REMARK:ジョブをキャンセルします。
mysql> cancel ddl 1103798959568478208; Query OK, 2 rows affected (0.03 sec)ジョブを再度照会し、その状態を確認します。
mysql> show ddl\G *************************** 1. row *************************** JOB_ID: 1103798959568478208 OBJECT_SCHEMA: ddltest OBJECT_NAME: test_mdb_mtb JOB_TYPE: CREATE_TABLE PHASE: EXECUTE STATE: PENDING PROGRESS: 87% START_TIME: 2019-08-29 14:57:20.058 END_TIME: 2019-08-29 14:57:28.899 ELAPSED_TIME(MS): 8841 DDL_STMT: create table test_mdb_mtb (c1 int not null auto_increment primary key, c2 varchar(10), c3 date) dbpartition by hash(c1) tbpartition by hash(c1) tbpartitions 64 REMARK: ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] The job '1103798959568478208' has been cancelled.ジョブは現在
PENDING状態です。REMARKフィールドは、ジョブがキャンセルされたことを確認します(ERR_DDL_JOB_ERROR)。保留中のジョブを解決するには、RECOVER DDLまたはROLLBACK DDLを使用します。
ジョブの削除
REMOVE DDL は、PENDING 状態の DDL ジョブを削除し、関連する内部キャッシュをクリアします。
保留中のジョブを削除すると、中間 DDL 実行状態が公開され、同一オブジェクトに対するその後の操作に干渉する可能性があります。RECOVER DDL または ROLLBACK DDL を可能な限り REMOVE DDL よりも優先してください。ジョブを再開またはロールバックできない場合にのみ、REMOVE DDL を使用してください。
構文
REMOVE DDL { ALL PENDING | <job_id> [, <job_id>] ... }パラメーター
| パラメーター | 説明 |
|---|---|
ALL PENDING | すべての PENDING ジョブを削除し、内部キャッシュをクリアします。 |
job_id | 削除する PENDING ジョブの ID です。JOB_ID フィールドの値は、SHOW DDL の出力から取得します。 |
例
この例では、参照整合性制約により DROP TABLE ジョブが失敗し、テーブルにアクセスできなくなるシナリオを示します。DROP TABLE はロールバックをサポートしないため、保留中のジョブを削除する必要があります。
参照整合性制約を持つ既存の親テーブルおよび子テーブルを確認します。
mysql> show create table test_parent\G *************************** 1. row *************************** Table: test_parent Create Table: CREATE TABLE `test_parent` ( `id` int(11) NOT NULL, `pkey` int(11) NOT NULL, `col` int(11) DEFAULT NULL, PRIMARY KEY (`id`,`pkey`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`id`) 1 row in set (0.01 sec) mysql> show create table test_child\G *************************** 1. row *************************** Table: test_child Create Table: CREATE TABLE `test_child` ( `id` int(11) DEFAULT NULL, `parent_id` int(11) DEFAULT NULL, KEY `parent_id` (`parent_id`), CONSTRAINT `test_child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `test_parent` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`parent_id`) 1 row in set (0.02 sec)親テーブルの削除を試みます。外部キー制約により
test_childがtest_parentを参照しているため、操作は失敗します。mysql> drop table test_parent; ERROR 4636 (HY000): [f518265d0066000][10.81.69.55:3306][ddltest]ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] Not all physical operations have been done successfully: expected 9, but done 0. Caused by: 1217:DDLTEST_1562056402230OYMK_7WW7_0007:Cannot delete or update a parent row: a foreign key constraint fails on `test_parent`;...DDL ジョブを照会し、PENDING 状態であることを確認します。
mysql> show ddl\G *************************** 1. row *************************** JOB_ID: 1103806757547171840 OBJECT_SCHEMA: ddltest OBJECT_NAME: test_parent JOB_TYPE: DROP_TABLE PHASE: EXECUTE STATE: PENDING PROGRESS: 0% START_TIME: 2019-08-29 15:28:19.240 END_TIME: 2019-08-29 15:28:19.456 ELAPSED_TIME(MS): 216 DDL_STMT: drop table test_parent REMARK: ERR-CODE: [TDDL-4636][ERR_DDL_JOB_ERROR] Not all physical operations have been done successfully: expected 9, but done 0. Caused by: 1217:DDLTEST_1562056402230OYMK_7WW7_0007:Cannot delete or update a parent row: a foreign key constraint fails on `test_pare ...REMARKにより、外部キー制約が削除をブロックしたことが確認されます。進行率が 0 % のため、物理削除は一切行われておらず、テーブル構造はそのまま残っています。テーブルのデータが整合性を保っていることを確認します。
mysql> check table test_parent; +---------------------------------------+-------+----------+----------+ | TABLE | OP | MSG_TYPE | MSG_TEXT | +---------------------------------------+-------+----------+----------+ | ddltest_1562056402230oymk.test_parent | check | status | OK | +---------------------------------------+-------+----------+----------+ 1 row in set (0.05 sec)ただし、保留中のジョブによりテーブルへのアクセスがブロックされています。
mysql> show tables like 'test_parent'; Empty set (0.00 sec) mysql> show create table test_parent; ERROR 4642 (HY000): [f5185a78b066000][10.81.69.55:3306][ddltest]ERR-CODE: [TDDL-4642][ERR_UNKNOWN_TABLE] Unknown table 'ddltest.test_parent'テーブルは整合性を保っていますが、到達不能です。DROP TABLE はロールバックをサポートしないため、失敗したジョブを削除してアクセスを復元します。
保留中のジョブを削除します。
mysql> remove ddl 1103806757547171840; Query OK, 1 row affected (0.02 sec)テーブルが再びアクセス可能であることを確認します。
mysql> show tables like 'test_parent'; +-------------------+ | TABLES_IN_DDLTEST | +-------------------+ | test_parent | +-------------------+ 1 row in set (0.01 sec)テーブルが表示され、アクセス可能です。DROP TABLE 操作を再試行する前に、参照整合性制約を解消してください。