データポンプ・トランスポータル表領域での移行

移行検証の一環として、11.2 to 12.2のデータポンプ・トランスポータル表領域での移行を試した際の手順まとめ。

## 前提
OnP側がリトル・エンディアンで且つ、 
クラウド側のDBのデータベース・キャラクタ・セットに互換性がある場合にのみ使用できます。

尚、エンディアンの確認は以下SQLで可能です。

```
SQL> set lines 150 pages 10000
SQL> col platform_name for a50;
SQL> col endian_format for a20
SQL> SELECT * FROM v$transportable_platform ORDER BY platform_id;

PLATFORM_ID PLATFORM_NAME                                      ENDIAN_FORMAT
----------- -------------------------------------------------- --------------------
          1 Solaris[tm] OE (32-bit)                            Big
          2 Solaris[tm] OE (64-bit)                            Big
          3 HP-UX (64-bit)                                     Big
          4 HP-UX IA (64-bit)                                  Big
          5 HP Tru64 UNIX                                      Little
          6 AIX-Based Systems (64-bit)                         Big
          7 Microsoft Windows IA (32-bit)                      Little
          8 Microsoft Windows IA (64-bit)                      Little
          9 IBM zSeries Based Linux                            Big
         10 Linux IA (32-bit)                                  Little
         11 Linux IA (64-bit)                                  Little
         12 Microsoft Windows x86 64-bit                       Little
         13 Linux x86 64-bit                                   Little
         15 HP Open VMS                                        Little
         16 Apple Mac OS                                       Big
         17 Solaris Operating System (x86)                     Little
         18 IBM Power Based Linux                              Big
         19 HP IA Open VMS                                     Little
         20 Solaris Operating System (x86-64)                  Little
         21 Apple Mac OS (x86-64)                              Little

20行が選択されました。

SQL> SELECT platform_name FROM V$DATABASE;

PLATFORM_NAME
-----------------------------
Linux x86 64-bit
```

## 手順

##### 1. OnPで、データポンプのトランスポータブル表領域エクスポート用にDBを準備。

```
### A. OnP上にDMPを出力するディレクトリオブジェクトを用意 ###

[oracle@vmiwatest work]$ mkdir -m 755 dmp
[oracle@vmiwatest work]$ cd dmp/
[oracle@vmiwatest dmp]$ sqlplus / as sysdba
・・・
SQL> create directory iwadmp as '/oracle/work/dmp';
ディレクトリが作成されました。

SQL> GRANT read,write ON DIRECTORY iwadmp TO iwate;
権限付与が成功しました。

### B. 移行対象となる表領域に属するデータファイルをDBA_DATA_FILESを使って特定 ###

SQL> col TABLESPACE_NAME for a30
SQL> col FILE_NAME for a70
SQL> SELECT tablespace_name ,file_name FROM dba_data_files;

TABLESPACE_NAME                FILE_NAME
------------------------------ ----------------------------------------------------------------------
SYSTEM                         /oracle/app/oracle/oradata/ora112/system01.dbf
SYSAUX                         /oracle/app/oracle/oradata/ora112/sysaux01.dbf
UNDOTBS1                       /oracle/app/oracle/oradata/ora112/undotbs01.dbf
USERS                          /oracle/app/oracle/oradata/ora112/users01.dbf
IWATEST_TPT_DATA               /oracle/app/oracle/oradata/ora112/iwatest_tpt_data01.dbf
IWATEST_TPT_IDX                /oracle/app/oracle/oradata/ora112/iwatest_tpt_idx01.dbf
IWATEST_MAS_DATA               /oracle/app/oracle/oradata/ora112/iwatest_mas_data01.dbf
IWATEST_MAS_IDX                /oracle/app/oracle/oradata/ora112/iwatest_mas_idx01.dbf
ORATEST                        /oracle/app/oracle/oradata/ora112/oratest.dbf

SQL> SELECT d.tablespace_name "NAME", d.status "STATUS",
  2     TO_CHAR((a.bytes / 1024 / 1024 / 1024),'99,999,990.900') "SIZE(G)",
  3     TO_CHAR(((a.bytes - DECODE(f.bytes, NULL, 0, f.bytes)) / 1024 / 1024 / 1024),'99,999,990.900') "USED(G)"
  4  FROM  sys.dba_tablespaces d, sys.sm$ts_avail a, sys.sm$ts_free f
  5  WHERE  d.tablespace_name = a.tablespace_name
  6     AND f.tablespace_name (+)= d.tablespace_name
  7     AND d.tablespace_name = 'IWATEST_TPT_DATA';

NAME                           STATUS                      SIZE(G)         USED(G)
------------------------------ --------------------------- --------------- ---------------
IWATEST_TPT_DATA               ONLINE                                2.000           1.543

### C. 転送する表領域をREAD ONLYモードに設定 ###
   ※該当表領域に含まれる表でINDEXや外部キーを別表領域に設定している表がある場合は、
   　それらの表領域も読み取り専用にする必要がある(expdp時に同時にエクスポートする必要がある)。

SQL> EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('IWATEST_TPT_DATA', TRUE);
PL/SQL procedure successfully completed.

SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
no rows selected
※違反している場合はORA-39908等違反している内容が出力

SQL> ALTER TABLESPACE iwatest_tpt_data READ ONLY;

表領域が変更されました。

SQL> SELECT d.tablespace_name "NAME", d.status "STATUS",
  2     TO_CHAR((a.bytes / 1024 / 1024 / 1024),'99,999,990.900') "SIZE(G)",
  3     TO_CHAR(((a.bytes - DECODE(f.bytes, NULL, 0, f.bytes)) / 1024 / 1024 / 1024),'99,999,990.900') "USED(G)"
  4  FROM  sys.dba_tablespaces d, sys.sm$ts_avail a, sys.sm$ts_free f
  5  WHERE  d.tablespace_name = a.tablespace_name
  6     AND f.tablespace_name (+)= d.tablespace_name
  7  ORDER BY f.tablespace_name ASC;

NAME                           STATUS                      SIZE(G)         USED(G)
------------------------------ --------------------------- --------------- ---------------
IWATEST_TPT_DATA               READ ONLY                             3.000           1.543
IWATEST_TPT_IDX                READ ONLY                             2.488           0.008
IWATEST_MAS_DATA               READ ONLY                             3.000           0.012
IWATEST_MAS_IDX                READ ONLY                             2.000           0.008
```

#####2. SQL*Plusを抜けてから、TRANSPORT_TABLESPACESオプションを使用してエクスポートを実施

```
[oracle@vmiwatest ~]$ date; expdp iwate/xxxxx TRANSPORT_TABLESPACES=iwatest_tpt_data, \
iwatest_tpt_idx,iwatest_mas_data, iwatest_mas_idx \
TRANSPORT_FULL_CHECK=yes DIRECTORY=iwadmp; date
2018年  8月 21日 火曜日 17:41:31 JST

Export: Release 11.2.0.4.0 - Production on 火 8月 21 17:41:31 2018

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

接続先: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
"IWATE"."SYS_EXPORT_TRANSPORTABLE_01"を起動しています: iwate/******** TRANSPORT_TABLESPACES=iwatest_tpt_data,iwatest_tpt_idx,iwatest_mas_data,iwatest_mas_idx TRANSPORT_FULL_CHECK=yes DIRECTORY=iwadmp
オブジェクト型TRANSPORTABLE_EXPORT/PLUGTS_BLKの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/TABLEの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/GRANT/OWNER_GRANT/OBJECT_GRANTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/INDEX/INDEXの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/INDEX_STATISTICSの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/COMMENTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/REF_CONSTRAINTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/TABLE_STATISTICSの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLKの処理中です
マスター表"IWATE"."SYS_EXPORT_TRANSPORTABLE_01"は正常にロード/アンロードされました
******************************************************************************
IWATE.SYS_EXPORT_TRANSPORTABLE_01に設定されたダンプ・ファイルは次のとおりです:
  /oracle/work/dmp/expdat.dmp
******************************************************************************
トランスポータブル表領域IWATEST_TPT_DATAにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_tpt_data01.dbf
トランスポータブル表領域IWATEST_TPT_IDXにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_tpt_idx01.dbf
トランスポータブル表領域IWATEST_MAS_DATAにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_mas_data01.dbf
トランスポータブル表領域IWATEST_MAS_IDXにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_mas_idx01.dbf
ジョブ"IWATE"."SYS_EXPORT_TRANSPORTABLE_01"が火 8月 21 17:42:09 2018 elapsed 0 00:00:38で正常に完了しました

2018年  8月 21日 火曜日 17:42:10 JST
[oracle@vmiwatest ~]$ ls -ltr /oracle/work/dmp/
合計 12208
-rw-r-----. 1 oracle oinstall 12496896  8月 21 17:42 2018 expdat.dmp
-rw-r--r--. 1 oracle oinstall     2450  8月 21 17:42 2018 export.log
```

#####3. expdpのDMPおよび表領域データファイルをクラウド上に転送。

転送方法はマニュアルにある様なSCPコマンドでなく、WinSCPなどのツールでも問題なさそう。 
自分はWinSCPを使用してローカル経由で転送しましたが、問題はありませんでした。

#####4. OnP環境の対象表領域をREAD WRITEに戻す。

```
SQL> COL tablespace_name FOR a30
SQL> SELECT tablespace_name,status FROM DBA_TABLESPACES WHERE tablespace_name LIKE 'IWA%';

TABLESPACE_NAME                STATUS
------------------------------ ---------------------------
IWATEST_TPT_DATA              READ ONLY
IWATEST_TPT_IDX               READ ONLY
IWATEST_MAS_DATA              READ ONLY
IWATEST_MAS_IDX               READ ONLY

SQL> ALTER TABLESPACE iwatest_tpt_data READ WRITE;
表領域が変更されました。

SQL> ALTER TABLESPACE iwatest_tpt_idx READ WRITE;
表領域が変更されました。

SQL> ALTER TABLESPACE iwatest_mas_data READ WRITE;
表領域が変更されました。

SQL> ALTER TABLESPACE iwatest_mas_idx READ WRITE;
表領域が変更されました。

SQL> SELECT tablespace_name,status FROM DBA_TABLESPACES WHERE tablespace_name LIKE 'IWA%';

TABLESPACE_NAME                STATUS
------------------------------ ---------------------------
IWATEST_TPT_DATA               ONLINE
IWATEST_TPT_IDX                ONLINE
IWATEST_MAS_DATA               ONLINE
IWATEST_MAS_IDX                ONLINE
```

#####5. クラウド上で、表領域インポート用にDBを準備。 
　基本的には事前に準備はしていると思いますが、以下の様な点は注意。

・エンディアンの確認。 
・同じ表領域名を持つ表領域が存在しないか(ないとは思いますが)。 
　もし存在する場合は移行先のDBの表領域名を変更することで回避可能(移行元の表領域名を変更して再度Expdpも有)。 
・移行元と移行先のキャラクタ・セット、各国語キャラクタ・セットが同じか。 
・インポートされるオブジェクトの所有者が存在するか。 
　トランスポータブル表領域モードのインポートでは、ユーザーは作成されないので。

#####6. クラウド上でimpdpを起動し、DBに接続。

```
[oracle@test122 dmp]$ impdp iwate/ahoo@pdb1 DIRECTORY=iwaimp 
TRANSPORT_DATAFILES='/u02/app/oracle/oradata/test122/PDB1/iwatest_tpt_data01.dbf', 
'/u02/app/oracle/oradata/test122/PDB1/iwatest_mas_data01.dbf',
'/u02/app/oracle/oradata/test122/PDB1/iwatest_tpt_idx01.dbf', 
'/u02/app/oracle/oradata/test122/PDB1/iwatest_mas_idx01.dbf'

Import: Release 12.2.0.1.0 - Production on 木 8月 23 13:26:22 2018

Copyright (c) 1982, 2017, Oracle and/or its affiliates.  All rights reserved.

接続先: Oracle Database 12c EE High Perf Release 12.2.0.1.0 - 64bit Production
マスター表"IWATE"."SYS_IMPORT_TRANSPORTABLE_01"は正常にロード/アンロードされました
ソース・タイムゾーンは+09:00で、ターゲット・タイムゾーンは+00:00です。
"IWATE"."SYS_IMPORT_TRANSPORTABLE_01"を起動しています: iwate/********@pdb1 DIRECTORY=iwaimp TRANSPORT_DATAFILES=/u02/app/oracle/oradata/test122/PDB1/iwatest_tpt_data01.dbf, /u02/app/oracle/oradata/test122/PDB1/iwatest_mas_data01.dbf, /u02/app/oracle/oradata/test122/PDB1/iwatest_tpt_idx01.dbf, /u02/app/oracle/oradata/test122/PDB1/iwatest_mas_idx01.dbf
オブジェクト型TRANSPORTABLE_EXPORT/PLUGTS_BLKの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/TABLEの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/GRANT/OWNER_GRANT/OBJECT_GRANTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/INDEX/INDEXの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/INDEX_STATISTICSの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/COMMENTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/REF_CONSTRAINTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLKの処理中です
ジョブ"IWATE"."SYS_IMPORT_TRANSPORTABLE_01"が木 8月 23 13:27:19 2018 elapsed 0 00:00:54で正常に完了しました
```

#####7. クラウド上の表領域をREAD WRITEモードに設定。 
  この際のコマンドは「4.」と同じ。  

#####8. データが正常にインポートされたことが確認できたら、DMPを削除可。

```
SQL> SELECT * FROM STATES;

        ID REGION                  PREFECTURE                     PREFECTURAL_CAPITAL            CREATED
---------- ----------------------- ------------------------------ ------------------------------ --------
         1 Hokkaido                Hokkaido                       Sapporo                        18-08-21
         2 Tohoku                  Aomori                         Aomori                         18-08-21
         3 Tohoku                  Iwate                          Morioka                        18-08-21
         4 Tohoku                  Miyagi                         Sendai                         18-08-21
         5 Tohoku                  Akita                          Akita                          18-08-21
         6 Tohoku                  Yamagata                       Yamagata                       18-08-21
・・・
```


## 余談
トランスポータブル表領域ではエクスポートするのはメタデータの様なので、 
対象表領域の使用量はそこまで関係ないのかもしれない。

```
NAME                          STATUS          SIZE(G)         USED(G)
----------------------------- --------------- --------------- ---------------
IWATEST_TPT_DATA              READ ONLY                 2.000           1.543
IWATEST_TPT_IDX               READ ONLY                 1.000           0.023
IWATEST_MAS_DATA              READ ONLY                 1.000           0.020
IWATEST_MAS_IDX               READ ONLY                 1.000           0.020
```

上記の様に対象表領域のサイズを少し小さくした状態で再度エクスポートを実施したところ、
実行時間は下記の通りだった。

```
[oracle@vmiwatest ~]$ expdp iwate/iwate TRANSPORT_TABLESPACES=iwatest_tpt_data,iwatest_tpt_idx,iwatest_mas_data,iwatest_mas_idx TRANSPORT_FULL_CHECK=yes DIRECTORY=iwadmp dumpfile=tpt_test_iwatest_aft.dmp

Export: Release 11.2.0.4.0 - Production on 金 8月 24 15:16:50 2018
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

接続先: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
"IWATE"."SYS_EXPORT_TRANSPORTABLE_01"を起動しています: iwate/******** TRANSPORT_TABLESPACES=iwatest_tpt_data,iwatest_tpt_idx,iwatest_mas_data,iwatest_mas_idx TRANSPORT_FULL_CHECK=yes DIRECTORY=iwadmp dumpfile=tpt_test_iwatest_aft.dmp
オブジェクト型TRANSPORTABLE_EXPORT/PLUGTS_BLKの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/TABLEの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/GRANT/OWNER_GRANT/OBJECT_GRANTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/INDEX/INDEXの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/INDEX_STATISTICSの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/COMMENTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/CONSTRAINT/REF_CONSTRAINTの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/TABLE_STATISTICSの処理中です
オブジェクト型TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLKの処理中です
マスター表"IWATE"."SYS_EXPORT_TRANSPORTABLE_01"は正常にロード/アンロードされました
******************************************************************************
IWATE.SYS_EXPORT_TRANSPORTABLE_01に設定されたダンプ・ファイルは次のとおりです:
  /oracle/work/dmp/tpt_test_iwatest_aft.dmp
******************************************************************************
トランスポータブル表領域IWATEST_TPT_DATAにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_tpt_data01.dbf
トランスポータブル表領域IWATEST_TPT_IDXにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_tpt_idx01.dbf
トランスポータブル表領域IWATEST_MAS_DATAにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_mas_data01.dbf
トランスポータブル表領域IWATEST_MAS_IDXにはデータファイルが必要です:
  /oracle/app/oracle/oradata/ora112/iwatest_mas_idx01.dbf
ジョブ"IWATE"."SYS_EXPORT_TRANSPORTABLE_01"が金 8月 24 15:17:24 2018 elapsed 0 00:00:33で正常に完了しました
```


----

もし検証の通り、表領域の使用率が処理時間に関係ない場合、通常のDataPumpよりもexpdp/impdpの時間は確かに抑えられるはずです。
ただ、データファイル自体を移行するため、表領域を構成するデータファイルの数やサイズによっては通常のDataPumpよりも時間がかかることもあるのかな？などと思うところで。