15.2 移行方法

この項では、LONGまたはBasicFile LOBデータをSecureFile記憶域に移行するために使用できる様々な方法について説明します。

内容は次のとおりです。

15.2.1 SecureFiles移行ユーティリティを使用したLOBの移行

これは、BasicFile LOBデータをSecureFile記憶域に移行するために推奨される方法です。

このユーティリティは、オンライン再定義によって提供されるすべての機能をカプセル化し、一連のAPIコールの手動実行に伴う時間と労力を節約します。

15.2.1.1 SecureFiles移行ユーティリティについて

SecureFiles移行ユーティリティを使用して、次のタスクを実行できます:

  • データを圧縮せずに、BasicFile LOBデータをSecureFile記憶域に移行します。
  • BasicFile LOBを圧縮されたSecureFile LOBに移行します。
  • 圧縮されていないSecureFile LOBを圧縮されたSecureFile LOBに移行します。

SecureFiles移行ユーティリティを2回実行するフローチャート

LOBを圧縮および移行するには、次のフローチャートに示すように、SecureFiles移行ユーティリティを2回実行します。最初の実行では、ユーティリティは指定されたLOBを分析し、移行および圧縮の推奨事項を含むレポートを生成します。レポートをレビューした後、レポートを確認または更新して、移行または圧縮するLOBを指定します。仮表を作成し、ユーティリティを再度実行してLOBを移行および圧縮します。


securefiles移行ユーティリティのフローチャート

長所

  • 表またはパーティションをオフラインにする必要がありません。
  • データベース、スキーマ、表またはLOBセグメント・レベルで移行を実行します。
  • データの移行後、SecureFiles移行ユーティリティを使用してSecureFile LOBを圧縮することもできます。

短所

  • 必要な表またはパーティション全体、およびすべてのLOBセグメントに等しい追加の記憶域が必要
  • グローバル索引の再作成が必要。

15.2.1.2 SecureFiles移行ユーティリティを使用したLOBの移行

SecureFiles移行ユーティリティを使用してBasicFile LOBデータをSecureFile記憶域に移行するには:
  1. 自動セグメント領域管理(ASSM)を使用して表領域を作成するか、既存の表領域を使用します。表領域の名前を書き留めます。

    サンプル・コード

    次のコマンドは、LOBTEMP1という名前のASSM表領域を作成します。

    CREATE TABLESPACE LOBTEMP1 DATAFILE 'lobtemp1.dbf' SIZE 1G REUSE AUTOEXTEND ON SEGMENT SPACE MANAGEMENT AUTO;
  2. この表領域に関連付けられるユーザーを作成します。関連付けられたユーザーを持つ既存のASSM表領域を使用する場合は、このステップをスキップできます。

    SecureFiles移行ユーティリティを実行すると、このユーザーに対してレポートが作成されます。

    サンプル・コード

    次のコマンドは、temp1という名前のユーザーを作成します。また、ユーザーは、前のステップで作成したASSM表領域であるLOBTEMP1に関連付けられます。

    CREATE USER temp1 identified by temp1 DEFAULT TABLESPACE LOBTEMP1;
  3. SecureFiles移行ユーティリティを実行するすべてのスキーマに、この表領域にアクセスするための適切な権限があることを確認します。そうしないと、エラーが発生する可能性があります(表領域に対するユーザーの割当て容量が不足するなど)。
  4. SYSユーザーとして、表の作成用に記述された次のコマンドを実行します。
    create table migration_config (ctime date, data clob , constraint c1 check(data is json));

    後でスクリプトを実行するときに、作成したmigration_config表からデータが読み取られます。

  5. 移行するスキーマ、表および列を指定する単一の行を表に挿入します。スクリプトを初めて実行する場合は、run_typeの値としてfirstと入力します。他のユーザーには、環境に基づいて値を指定してください。

    コマンドの例

    次の例は、migration_config表に単一行を挿入する方法を示しています。

    insert into migration_config values
        (systimestamp,
        '{"schema_name" : ["TEST2"],
        "table_name" : ["TEST1.TAB_DEFERRED_SEGCREATION1", "TEST1.TAB_NON_LOB1",
        "TEST1.BASIC1A", "TEST1.BASIC3A"],
        "column_name" : ["TEST1.TAB_PARTS1.a",
        "TEST1.BASIC123.a", "TEST1.BASIC125.a"],
        "metadata_schema_name" : "TEMP1",
        "metadata_tablespace_name" : "LOBTEMP1",
        "run_type" : "first", 
        "compress_storage_rec_threshold" : 5000, 
        "directory_path" : "<full path to folder for log files>",
        "trace" : 1}');

    説明

    • schema_name: キー名の指定は必須ですが、値はオプションです。移行および圧縮するスキーマ名のカンマ区切りリストを指定します。値{"schema_name" : []}を指定しない場合、スキーマ全体が移行されません。かわりに、スクリプトは、table_nameまたはcolumn_name配列で指定できる詳細な粒度を確認します。
    • table_name: キー名の指定は必須ですが、値はオプションです。移行および圧縮する表のカンマ区切りリストを指定します。名前は<schema_name>.<table_name>という形式で入力する必要があります。スキーマ名には表名の接頭辞が付きます。次の例では、TEST1はスキーマの名前、BASIC1AおよびBASIC3Aは表の名前です。
      "table_name" : ["TEST1.BASIC1A", "TEST1.BASIC3A"]

      "table_name" : []を指定しない場合、スクリプトは、column_name配列で指定できる詳細な粒度を確認します。

    • column_name: キー名の指定は必須ですが、値はオプションです。移行および圧縮する列のカンマ区切りリストを指定します。名前は、<schema_name>.<table_name>.<column_name>という形式で入力する必要があります。スキーマ名と表名は、列名に接頭辞を付けます。

      "column_name" : []を指定しない場合、指定した表に属するすべてのLOB列が移行されます。

    • metadata_schema_name: 必須。一意のスキーマ名を入力します。スクリプトは、このスキーマを使用して、移行中に生成されたメタデータ表またはレポートを格納します。スキーマには、中間データを格納するためのデフォルトのASSM表領域が必要です。
    • metadata_tablespace_name: 必須。metadata_schema_nameで指定されたスキーマが属するASSM表領域の名前を指定します。これは、最初のステップでコピーしたASSM表領域の名前です。
    • run_type: 必須。許可される値は、スクリプトを実行する2つのステージに対応するfirstおよびsecondです。
    • compress_storage_rec_threshold: オプション。スクリプトでは、入力した記憶域のしきい値を超えるLOBの圧縮が推奨されます。デフォルト値は5000MBです。
    • directory_path: オプション。trace1に設定されている場合、生成されたログ・ファイルを保存するフォルダへの完全パスを入力します。トレースを有効にしない場合、directory_pathキーを指定する必要はありません。
    • trace: オプショントレースを有効にするには、これを1に設定します。securefile_migration_utility.logという名前のログ・ファイルが作成され、directory_pathで指定したフォルダ・パスに保存されます。値を入力しないと、ログ・ファイルが生成されません。

    指定したスキーマのすべての表のすべてのLOB列を移行および圧縮する挿入の例

    次の例では、migration_config表にエントリを挿入して、スクリプトの実行時に、指定したスキーマ(TEST1およびTEST2)内のすべての表のLOB列を移行します。

    insert into migration_config values 
        (systimestamp,
        '{"schema_name" : ["TEST1","TEST2"],
        "table_name" : [], 
        "column_name" : [], 
        "metadata_schema_name" : "TEMP1",
        "metadata_tablespace_name" : "LOBTEMP1",
        "run_type" : "first", 
        "directory_path" : "<full_path>",
        "trace" : 1}');

    すべてのスキーマのすべての表のすべてのLOB列を移行および圧縮する挿入の例

    次の例では、migration_config表にエントリを挿入して、スクリプトの実行時に、すべてのスキーマ、表、および列のすべてのLOB列を移行して圧縮します。

    insert into migration_config values (
        systimestamp,
        '{"schema_name" : [],
        "table_name" : [], 
        "column_name" : [],
        "metadata_schema_name" : "TEMP1",
        "metadata_tablespace_name" : "LOBTEMP1",
        "run_type" : "first", 
        "directory_path" : "<full_path>",
        "trace" : 1}');
  6. migration_config表を作成し、必要な構成の詳細を含む行を挿入した後、SYSユーザーとしてスクリプトを実行します。
    SQL> @securefile_migration_script.sql

    次のレポートが生成され、一時表領域に表として格納されます。前のステップで、一時表領域の名前をmetadata_schema_nameに指定しました。

    • sf_migration_table_ddl_report表には、すべてのユーザーについて、指定したスキーマ内のすべての表に関するDDL情報の詳細が示されます。
    • sf_migration_index_ddl_report表には、すべてのユーザーについて、指定したスキーマ内のすべての表に関する索引DDL情報の詳細が示されます。
    • sf_migration_basicfile_report表には、すべてのユーザーのすべてのBasicFile LOBセグメントがリストされ、記憶域、圧縮率、圧縮の推奨事項、圧縮タイプなどのBasicFile LOBの詳細が示されます。この表のCOMPRESS_RECOMMENDATION列には、圧縮する必要があるBasicFile LOBに関する推奨事項がY (はい)またはN (いいえ)として含まれています。
    • sf_migration_lob_statistics_report表のCOMPRESS_RECOMMENDATION列には、圧縮する必要があるSecureFile LOBに関する推奨事項がY (はい)またはN (いいえ)として含まれています。また、記憶域、圧縮率、圧縮の推奨事項、圧縮タイプなど、SecureFile LOBの詳細も表示されます。
    • sf_migration_basicfile_migration_report表が生成されます。移行が完了した後にのみデータが移入されます。これは、run_typesecondに設定してからスクリプトを再度実行したときに実行されます。
    • sf_migration_lob_migration_report表が生成されます。移行が完了した後にのみデータが移入されます。これは、run_typesecondに設定してからスクリプトを再度実行したときに実行されます。
  7. 推奨に従って移行または圧縮しないBasicFile LOBを識別するには、sf_migration_basicfile_reportを参照してください。推奨事項に従って圧縮しないSecureFile LOBを識別するには、sf_migration_lob_statistics_reportを参照してください。LOBを圧縮または移行しない場合は、それぞれのレポートを更新します。
    • LOBを圧縮しない場合は、圧縮しない特定のLOBについて、sf_migration_lob_statistics_reportcompress_recommendation列の値をNに更新します。すべてのLOBのデフォルト値はYです。
    • 移行しないBasicFile LOBがある場合は、移行しない特定のLOBについて、sf_migration_basicfile_reportAllow migrate列の値をNに更新します。すべてのLOBのデフォルト値はYです。

    BasicFile LOBをSecureFile LOBに移行することをお薦めします。

  8. 元の表を所有する同じユーザーの下に仮表を作成します。sf_migration_basicfile_migration_reportまたはsf_migration_lob_migration_reportレポートのinterim_table列に示されている名前で仮表を作成する必要があります。そうしないと、スクリプトは仮表を見つけることができず、ora-00942 表が見つかりませんというエラー・メッセージで失敗します。

    SecureFiles移行ユーティリティを使用して移行するBasicFile LOBを含む実表があるとします。

    CREATE TABLE basic1a
    (
        a CLOB,
        b NUMBER
    );

    次の例は、仮表を作成して、basic1a表のBasicFile LOBをSecureFile圧縮LOBに、中程度の圧縮で移行する方法を示しています。

    CREATE TABLE basic1a_int1
    (
        a CLOB,
        b NUMBER
    ) lob(a) store as securefile (compress medium);
  9. 次のコマンドに示すように、挿入した行を更新して、run_typesecondに変更します。
    SQL> update migration_config set data = JSON_TRANSFORM(data, SET '$.run_type' = 'second');
  10. SYSユーザーとしてスクリプトを実行します。
    SQL> @securefile_migration_script.sql

    スクリプトは、sf_migration_lob_statistics_reportおよびsf_migration_basicfile_reportの推奨事項に基づいて、BasicFile LOBセグメントを圧縮または非圧縮のSecureFile LOBに移行し、SecureFile LOBセグメントを圧縮します。

    移行が正常に完了すると、スクリプトによって次のレポートが更新されます。これらの表には、LOBの圧縮の成功または失敗に関するステータスが示されます。

    • sf_migration_basicfile_migration_report表は、BasicFile LOBの移行の成功または失敗の詳細を示します。generated_ddl列には、新しい表のDDLの詳細が表示されます。
    • sf_migration_lob_migration_report表は、SecureFile LOBの圧縮の成功または失敗の詳細を示します。

15.2.2 オンライン再定義を使用したLOBの移行

オンライン再定義を使用して、複数のAPIコールを実行して、LONGまたはBasicFile LOBデータをSecureFile記憶域に移行します。

このタスクを自動化し、一連のAPIコールの手動実行に伴う時間と労力を節約するSecureFiles移行ユーティリティの使用を検討してください。「SecureFiles移行ユーティリティを使用したLOBの移行」を参照してください。
LONGからLOBへの移行のオンライン再定義は表レベルで実行する必要がありますが、BasicFileからSecureFileへの移行は表レベルまたはパーティション・レベルで実行できます。

オンライン再定義の利点

  • 表またはパーティションをオフラインにする必要がない。
  • パラレルで実行可能。
    オンライン再定義のパラレル実行を設定するには、次を実行します。
    ALTER SESSION FORCE PARALLEL DML;

オンライン再定義のデメリット

  • 必要な表またはパーティション全体、およびすべてのLOBセグメントに等しい追加の記憶域が必要
  • グローバル索引の再作成が必要。

例15-1 BasicFiles LOB記憶域からSecureFile LOB記憶域への表の移行のためのオンライン再定義

REM Grant privileges required for online redefinition.
GRANT EXECUTE ON DBMS_REDEFINITION TO pm;
GRANT ALTER ANY TABLE TO pm;
GRANT DROP ANY TABLE TO pm;
GRANT LOCK ANY TABLE TO pm;
GRANT CREATE ANY TABLE TO pm;
GRANT SELECT ANY TABLE TO pm;
REM Privileges required to perform cloning of dependent objects.
GRANT CREATE ANY TRIGGER TO pm;
GRANT CREATE ANY INDEX TO pm;
CONNECT pm/pm

-- This forces the online redefinition to execute in parallel
ALTER SESSION FORCE parallel dml;

DROP TABLE cust;
CREATE TABLE cust(c_id NUMBER PRIMARY KEY,
    c_zip NUMBER,
    c_name VARCHAR(30) DEFAULT NULL,
    c_lob CLOB
);
INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');
-- Creating Interim Table
-- There is no requirement to specify constraints because they are
-- copied over from the original table.
CREATE TABLE cust_int(c_id NUMBER NOT NULL,
    c_zip NUMBER,
    c_name VARCHAR(30) DEFAULT NULL,
    c_lob CLOB
) LOB(c_lob) STORE AS SECUREFILE (NOCACHE FILESYSTEM_LIKE_LOGGING);
DECLARE
    col_mapping VARCHAR2(1000);
BEGIN
-- map all the columns in the interim table to the original table
    col_mapping :=
    'c_id c_id , '||
    'c_zip c_zip , '||
    'c_name c_name, '||
    'c_lob c_lob';
DBMS_REDEFINITION.START_REDEF_TABLE('pm', 'cust', 'cust_int', col_mapping);
END;
/
DECLARE
    error_count pls_integer := 0;
BEGIN
    DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('pm', 'cust', 'cust_int',
      1, TRUE,TRUE,TRUE,FALSE, error_count);
    DBMS_OUTPUT.PUT_LINE('errors := ' || TO_CHAR(error_count));
END;
/
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('pm', 'cust', 'cust_int');
-- Drop the interim table
DROP TABLE cust_int;
DESC cust;
-- The following insert statement fails. This illustrates
-- that the primary key constraint on the c_id column is
-- preserved after migration.
INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');
SELECT * FROM cust;

例15-2 LONGデータ型からSecureFile LOBへの表の移行のためのオンライン再定義

LONGからLOBへの移行ステップは次のとおりです。
  • 空の仮表を作成します。再定義処理が完了すると、この表には移行済のデータが保持されます。この仮表で次の操作を行います。
    • 移行元の表にあるLONG列ごとにCLOB列またはNCLOB列を定義します。
    • 移行元の表にあるLONG RAW列ごとにBLOB列を定義します。
  • 再定義プロセスを開始します。そのためには、次のように、DBMS_REDEFINITION.START_REDEF_TABLEをコールし、TO_LOB演算子を使用して列マッピングを渡します。
    DBMS_REDEFINITION.START_REDEF_TABLE(
        'schema_name', 
        'original_table',
        'interim_table', 
        'TO_LOB(long_col_name) lob_col_name',
        'options_flag',
        'orderby_cols'); 
    long_col_nameは元の表で変換するLONG列またはLONG RAW列の名前で、lob_col_nameは仮表のLOB列の名前です。このLOB列に変換後のデータが保持されます。
  • DBMS_REDEFINITION.COPY_TABLE_DEPENDENTSプロシージャをコールします。詳細は、関連マニュアルを参照してください。
  • DBMS_REDEFINITION.FINISH_REDEF_TABLEプロシージャをコールします。詳細は、関連マニュアルを参照してください。

次の例は、LONGからLOBへの移行のオンライン再定義を示しています。

REM Grant privileges required for online redefinition.
GRANT execute ON DBMS_REDEFINITION TO pm;
GRANT ALTER ANY TABLE TO pm;
GRANT DROP ANY TABLE TO pm;
GRANT LOCK ANY TABLE TO pm;
GRANT CREATE ANY TABLE TO pm;
GRANT SELECT ANY TABLE TO pm;

REM Privileges required to perform cloning of dependent objects.
GRANT CREATE ANY TRIGGER TO pm;
GRANT CREATE ANY INDEX TO pm;

CONNECT pm/pm

-- This forces the online redefinition to execute in parallel
ALTER SESSION FORCE parallel dml;

DROP TABLE cust;
CREATE TABLE cust(c_id   NUMBER PRIMARY KEY,
                  c_zip  NUMBER,
                  c_name VARCHAR(30) DEFAULT NULL,
                  c_long LONG
                  );
INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');

-- Creating Interim Table 
-- There is no requirement to specify constraints because they are 
-- copied over from the original table.
CREATE TABLE cust_int(c_id  NUMBER NOT NULL,
                  c_zip  NUMBER,
                  c_name VARCHAR(30) DEFAULT NULL,
                  c_long CLOB
                  );

DECLARE
 col_mapping VARCHAR2(1000);
BEGIN
--  map all the columns in the interim table to the original table
 col_mapping :=
               'c_id             c_id  , '||
               'c_zip            c_zip , '||
               'c_name           c_name, '||
               'to_lob(c_long)   c_long';

DBMS_REDEFINITION.START_REDEF_TABLE('pm', 'cust', 'cust_int', col_mapping);
END;
/

DECLARE
 error_count PLS_INTEGER := 0;
BEGIN
  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('pm', 'cust', 'cust_int',
                                          1, true, true, true, false,
                                          error_count);

  DBMS_OUTPUT.PUT_LINE('errors := ' || to_char(error_count));
END;
/

EXEC  DBMS_REDEFINITION.FINISH_REDEF_TABLE('pm', 'cust', 'cust_int');

-- Drop the interim table
DROP TABLE cust_int;

DESC cust;

-- The following insert statement fails. This illustrates 
-- that the primary key constraint on the c_id column is 
-- preserved after migration. 

INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');

SELECT * FROM cust;

15.2.3 データ・ポンプを使用したLOBの移行

Oracle Data Pumpでは、ソース・データベース内の表を再作成するか、LOB列をSecureFiles LOBとして再作成できます。

Oracle Data Pumpによって表が再作成されるときは、デフォルトでは、それらの表は、ソース・データベース内にあるそれらと同じ状態で再作成されます。このため、LOB列がソース・データベースでBasicFiles LOBであった場合、Oracle Data Pumpではインポート先のデータベースのBasicFile LOBとして再作成が試みられます。ただし、コマンドラインでTRANSFORMパラメータを使用するか、DBMS_DATAPUMPおよびDBMS_METADATAパッケージでLOB_STORAGEパラメータを使用することで、再作成された表でSecureFile LOBとしてLOBを作成するよう強制できます。

例:
impdp system/manager directory=dpump_dir schemas=lobuser dumpfile=lobuser.dmp
      transform=lob_storage:securefile

ノート:

トランスポータブル・インポートでは名前の変換は無効です。

関連項目:

SecureFile LOBに変換するためのTRANSFORMパラメータを使用したTRANSFORM

キーワードHIDDENを使用すると、デフォルトのインラインLOBサイズをユーザー指定のサイズと区別できます。

例:
CREATE TABLE <tab> (…) LOB (L1) STORE AS … [ENABLE STORAGE IN ROW [4000|8000]
        HIDDEN];

データ・ポンプを使用したLOBの移行に関する制限事項

ASSM以外の表領域ではSecureFile LOBを使用できません。ソース・データベースにASSMをサポートしていない表領域のLOB列が含まれている場合、Oracleデータ・ダンプを使用し、LOB列にsecurefile句を使用して表を再作成すると、エラー・メッセージが表示されます。

LOB列を含むASSM以外の表をインポートするには、TRANSFORM=LOB_STORAGE:SECUREFILEを使用せずに、これらの表に対して別のインポートを実行します。

例:

impdp system/manager directory=dpump_dir schemas=lobuser dumpfile=lobuser.dmp