D.4 オンライン再定義を使用したJSONデータ型への移行
PL/SQLプロシージャDBMS_REDEFINITION.can_redef_table
によって許可された場合は、オンライン再定義を使用して、表データの可用性に大きな影響を与えることなく、テキストJSON列をJSON
型列に移行できます。移行プロセスの大部分で、問合せとDMLの両方に引き続きアクセスできます。
この方法では、元の表のデータを新しい仮表にコピーする一方で、元の表が通常のワークロードを引き続き処理します。
このように移行すると、通常のワークロードに使用可能な表が排他モードでロックされるのはわずかな時間の間だけで、これは表のサイズや再定義の複雑さには関係ありません。オンライン再定義には、再定義の対象となる表が使用している領域とほぼ同じ空き領域が必要です。
オンライン再定義を実行するには、パッケージDBMS_REDEFINITION
に対する実行権限が必要であり、マテリアライズド・ビューCREATE MVIEW
を作成する権限が必要です。
ここでは、table_owner
は表を所有するデータベース・スキーマです。
-
DBMS_REDEFINITION.can_redef_table
を起動して、オンライン再定義によって表を変更できるかどうかをチェックします。エラーが発生しなければ、ステップ2に進みます。EXEC DBMS_REDEFINITION.can_redef_table('table_owner', 'j_purchaseorder');
-
例4-1に似たコードを使用して、つまり元の表
j_purchaseorder
と同じ形状の、テキストJSON列ではなくJSON
型列が含まれる、仮表j_purchaseorder_new
を作成します。CREATE TABLE j_purchaseorder_new (id VARCHAR2(32), date_loaded TIMESTAMP(6) WITH TIME ZONE, data JSON);
-
元の表(
j_purchaseorder
)に仮想列がある場合は、仮表に同一の列を定義します。たとえば、このコードでは、最上位フィールドUser
およびCostCenter
に基づいて、それぞれ仮想列vc_user
およびvc_costcenter
を定義します。ALTER TABLE j_purchaseorder_new ADD (vc_user GENERATED ALWAYS AS (json_value(data, '$.User' RETURNING VARCHAR2(20)))); ALTER TABLE j_purchaseorder_new ADD (vc_costcenter GENERATED ALWAYS AS (json_value(data, '$.CostCenter' RETURNING VARCHAR2(6))));
-
プロシージャ
DBMS_REDEFINITION.start_redef_table
を使用して、JSON
データ型コンストラクタをテキストJSON列に適用します。BEGIN DBMS_REDEFINITION.start_redef_table('table_owner', 'j_purchaseorder', 'j_purchaseorder_new', 'ID ID, DATE_LOADED DATE_LOADED, JSON(DATA) PO_DOCUMENT', REFRESH_DEP_MVIEWS => 'Y', ENABLE_ROLLBACK => FALSE); END; /
-
元の表に制約、索引、仮想プライベート・データベース(VPD)ポリシーなどの依存物が含まれている場合は、プロシージャ
DBMS_REDEFINITION.copy_table_dependents
をコールして、それらを仮表にコピーします。DECLARE n_errors INTEGER; BEGIN DBMS_REDEFINITION.copy_table_dependents('table_owner', 'j_purchaseorder', 'j_purchaseorder_new', NUM_ERRORS => n_errors, IGNORE_ERRORS => FALSE); DBMS_OUTPUT.put_line(n_errors); END; /
-
(オプション)前のステップで元の表に対して大量のDML操作を発行した場合は、プロシージャ
DBMS_REDEFINITION.sync_interim_table
を使用してデータを仮表に同期させ、次のステップでの停止時間を最小限に抑えることを検討します。DBMS_REDEFINITION.sync_interim_table ('table_owner', 'j_purchaseorder', 'j_purchaseorder_new', PART_NAME => NULL, CONTINUE_AFTER_ERRORS => FALSE);
-
仮表が想定どおりに動作することを確認します。これが事実であると自分を納得させるために、必要と感じることは何でも実行します。次のステップ8 (元に戻すことはできません)では、2つの表の名前を入れ替えるので、現在の仮表は元の表名で"稼働"します。
仮表が想定どおりに動作していないことがチェックで判明した場合は、プロシージャ
DBMS_REDEFINITION.abort_redef_table
を使用して、これまでに行われた変更を元に戻すことができます。再定義中に再発した可能性がある問題を一掃し、これまでに作成された一時オブジェクト(マテリアライズド・ビュー・ログなど)を削除します。abort_redef_table
を使用すると、start_redef_table
の起動後でDBMS_REDEFINITION.finish_redef_table
の起動前であればいつでも、再定義プロセスを終了できます。DBMS_REDEFINITION.abort_redef_table ('table_owner', 'j_purchaseorder', 'j_purchaseorder_new', PART_NAME => NULL);
-
オンライン再定義を終了するには、プロシージャ
DBMS_REDEFINITION.finish_redef_table
を使用します。このアクションは元に戻すことができません。これにより、元の表と仮表の名前が入れ替わり、両方とも短い期間ロックされます。操作後、元の名前の表には再定義されたデータが格納され、仮名の表には元の(古い)データが格納されます。BEGIN DBMS_REDEFINITION.finish_redef_table('table_owner', 'j_purchaseorder', 'j_purchaseorder_new', DML_LOCK_TIMEOUT => 0); END; /
-
(オプション)元の(古い)データが現在格納されている仮表が不要になった場合は、削除します。必ず仮表を削除し、元の名前の表は削除しないでください。
PURGE
の指定はオプションです。PURGE
を使用すると、削除した表はリカバリできません。DROP TABLE 'table_owner', 'j_purchaseorder_new' CASCADE CONSTRAINTS PURGE;
関連項目:
-
Oracle Database管理者ガイドのオンラインでの表の再定義を参照してください
-
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のDBMS_REDEFINITONの概要に関する項
-
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のCAN_REDEF_TABLEプロシージャに関する項
-
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のSTART_REDEF_TABLEプロシージャに関する項
-
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のCOPY_TABLE_DEPENDENTSプロシージャに関する項
-
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のSYNC_INTERIM_TABLEプロシージャに関する項
-
『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のFINISH_REDEF_TABLEプロシージャに関する項
-
『Oracle Database SQL言語リファレンス』のDROP TABLEに関する項
親トピック: テキストJSONデータからJSONデータ型への移行