9iR2環境から18c環境のPDBにTTS(トランスポータブル表領域)でデータを移行してみる(Oracle Database)

表題の通り、9iR2環境から18c環境のPDBにTTS(トランスポータブル表領域)で
データを移行してみるやで彡(ﾟ)(ﾟ) 以下の構成で検証します。

 > 9iR2 ⇒ (トランスポータブル表領域) ⇒ 18c(PDB)

# 1. プラットフォーム、キャラクタセット、ブロックサイズの確認(9iR2 and 18c)

まず制限事項をクリアするため、プラットフォーム(OS)、キャラクタセット、ブロックサイズを確認します。
※TTS の 制限事項についてはマニュアルや My Oracle Support のドキュメントもご覧下さい。

```sh
# 9iR2環境
uname -a
Linux xxxxxxxx 2.6.9-55.ELsmp #1 SMP Fri Apr 20 17:03:35 EDT 2007 i686 i686 i386 GNU/Linux
```

```sql
-- 9iR2環境
SET LINESIZE 170;
SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production
PL/SQL Release 9.2.0.6.0 - Production
CORE    9.2.0.6.0       Production
TNS for Linux: Version 9.2.0.6.0 - Production
NLSRTL Version 9.2.0.6.0 - Production

SET LINESIZE 170;
SET PAGESIZE 100;
COLUMN PARAMETER FORMAT A50;
COLUMN VALUE FORMAT A80;
SELECT * FROM NLS_DATABASE_PARAMETERS;

PARAMETER                                          VALUE
-------------------------------------------------- --------------------------------------------------------------------------------
NLS_LANGUAGE                                       AMERICAN
：
NLS_CHARACTERSET                                   JA16SJIS ★
：
NLS_NCHAR_CHARACTERSET                             AL16UTF16 ★
：

SHOW PARAMETER DB_BLOCK_SIZE

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_block_size                        integer     8192
```

```sh
# 18c環境
uname -a
Linux xxxxxxxx 4.1.12-112.14.10.el6uek.x86_64 #2 SMP Mon Jan 8 18:24:01 PST 2018 x86_64 x86_64 x86_64 GNU/Linux
```

```sql
-- 18c環境
SHOW CON_NAME;

CON_NAME
------------------------------
PDB01

SET LINESIZE 170;
SELECT * FROM V$VERSION;

BANNER
--------------------------------------------------------------------------------
BANNER_FULL
-------------------------------------------------------------------------------------------
BANNER_LEGACY                                                                        CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.2.0.0.0
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production                    0

PARAMETER                                          VALUE
-------------------------------------------------- --------------------------------------------------------------------------------
NLS_RDBMS_VERSION                                  18.0.0.0.0
:
NLS_NCHAR_CHARACTERSET                             AL16UTF16 ★
NLS_CHARACTERSET                                   JA16SJIS ★
:

SHOW PARAMETER DB_BLOCK_SIZE

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_block_size                        integer     8192
```

# 2. 表領域を作成(9iR2) ※元々存在する表領域を移行する場合は不要

移行元の9iR2環境で表領域を作成します。
※元々存在する表領域を移行する場合は不要です彡(ﾟ)(ﾟ)

```sql
-- 9iR2
CREATE TABLESPACE TEST01
  DATAFILE '/u01/oracle/orcl/oradata/orcl/test01.dbf' SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED;

CREATE TABLESPACE TEST02
  DATAFILE '/u01/oracle/orcl/oradata/orcl/test02.dbf' SIZE 100M AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED;

表領域が作成されました。

表領域が作成されました。
```

# 3. オブジェクト作成(9iR2) ※元々存在するオブジェクトを移行する場合は不要

移行元の9iR2環境でオブジェクトを作成します。
※元々存在するオブジェクトを移行する場合は不要です彡(ﾟ)(ﾟ)

```sql
-- 9iR2
CONNECT AYSHIBAT/xxxxxxxx@yyyyyyyy
CREATE TABLE TBL_A (C1 NUMBER) TABLESPACE TEST01;
CREATE UNIQUE INDEX TBL_A_PK ON TBL_A(C1) TABLESPACE TEST02;
INSERT INTO TBL_A SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 1000;
COMMIT;

表が作成されました。

索引が作成されました。

1000行が作成されました。

コミットが完了しました。
```

# 4. 表領域が自己完結しているかを確認（DBMS_TTS.TRANSPORT_SET_CHECK）

表領域が自己完結しているかどうかをDBMS_TTSパッケージのTRANSPORT_SET_CHECKプロシージャと
TRANSPORT_SET_VIOLATIONSディクショナリで確認します。

下記例では、TEST02 が自己完結していない事が示されていますやね彡(ﾟ)(ﾟ)
TEST01表領域と一緒にトランスポートする必要があります。

```sql
# 9iR2
SET LINESIZE 100;
EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('TEST01', TRUE);
SELECT * FROM TRANSPORT_SET_VIOLATIONS;

PL/SQLプロシージャが正常に完了しました。

レコードが選択されませんでした。


EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('TEST02', TRUE);
SELECT * FROM TRANSPORT_SET_VIOLATIONS;

PL/SQLプロシージャが正常に完了しました。

VIOLATIONS
----------------------------------------------------------------------------------------------------
Index AYSHIBAT.TBL_A_PK in tablespace TEST02 points to table AYSHIBAT.TBL_A in tablespace TEST01
　　　　　　　　　　　　　 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^★TEST02は自己完結していない。

EXECUTE DBMS_TTS.TRANSPORT_SET_CHECK('TEST01,TEST02', TRUE);
SELECT * FROM TRANSPORT_SET_VIOLATIONS;

PL/SQLプロシージャが正常に完了しました。

レコードが選択されませんでした。
```

# 5. コピーする表領域を READ ONLY にする(9iR2)

移行元(9iR2)のコピー対象表領域を READ ONLY にします。

```sql
-- 9iR2
ALTER TABLESPACE TEST01 READ ONLY;
ALTER TABLESPACE TEST02 READ ONLY;

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

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

# 6. メタデータをエクスポート(9iR2)

移行元(9iR2)でメタデータ(定義情報)をエクスポートします。
9iR2環境なので Datapump は未実装です。従来型エクスポートを実行します。

```sh
# 9iR2
exp \'SYS/xxxxxxxx as sysdba\' TRANSPORT_TABLESPACE=y TABLESPACES=(TEST01,TEST02) FILE=test_meta.dmp LOG=exp_test_meta.log

Export: Release 9.2.0.6.0 - Production on 火 Sep 25 14:26:05 2018

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

接続先: Oracle9i Enterprise Edition Release 9.2.0.6.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 9.2.0.6.0 - Production
JA16SJISキャラクタ・セットおよびAL16UTF16 NCHARキャラクタ・セットでエクスポートが終了しました
注意: 表データ(行)はエクスポートされません。
トランスポータブル表領域メタデータをエクスポートします...
表領域TEST01 ...
. クラスタ定義をエクスポート中
. 表定義をエクスポート中
. 表                          TBL_Aをエクスポート中
表領域TEST02 ...
. クラスタ定義をエクスポート中
. 表定義をエクスポート中
. 参照整合性制約をエクスポート中
. トリガーをエクスポート中
. トランスポータブル表領域メタデータのエクスポートが終了しました。
エクスポートは警告なしで正常終了しました。
```

# 7. データファイルとメタデータdmpを移行先に転送(9iR2 ⇒ 18c)
scp等でデータファイルとメタデータdmpを移行先(18c)に転送します。
下記はデータファイルとメタデータを移行した後の結果です。

```sh
# 18c環境・転送後
$ pwd
/u01/app/oracle/oradata/SJISDB/7676F6B5B0D33571E0534656860A3EB5/datafile/
$ ls -la
total 22384272
drwxr-x--- 2 oracle oinstall       4096 Sep 25 06:00 .
drwxr-x--- 3 oracle oinstall       4096 Sep 22 13:45 ..
-rw-r----- 1 oracle oinstall  408952832 Sep 25 05:57 o1_mf_sysaux_ftdkv25s_.dbf
-rw-r----- 1 oracle oinstall  283123712 Sep 25 05:57 o1_mf_system_ftdkv25l_.dbf
-rw-r----- 1 oracle oinstall   65019904 Sep 24 01:15 o1_mf_temp_ftdkv25t_.dbf
-rw-r----- 1 oracle oinstall  104865792 Sep 25 05:57 o1_mf_undotbs1_ftdkv25t_.dbf
-rw-r----- 1 oracle oinstall  104865792 Sep 25 05:51 o1_mf_users_ftdplvyt_.dbf
-rw-r--r-- 1 oracle oinstall  104865792 Sep 25  2018 test01.dbf ★データファイル
-rw-r--r-- 1 oracle oinstall  104865792 Sep 25  2018 test02.dbf ★データファイル
-rw-r--r-- 1 oracle oinstall      16384 Sep 25  2018 test_meta.dmp ★メタデータdmp
```

# 8. 移行元の表領域を READ WRITE に戻す(9iR2)

移行元(9iR2)の表領域を READ WRITE に戻します。

```sql
-- 9iR2
ALTER TABLESPACE TEST01 READ WRITE;
ALTER TABLESPACE TEST02 READ WRITE;

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

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

# 9. メタデータを対象のPDBにインポート(18c)

メタデータを対象のPDBにインポートします。IMP-00403 の警告が出ますが、
下記マニュアルの記述を元に、必要に応じて生成されたSQLを手動実行して下さい。
※生成されたSQLが0バイトの場合は実行不要です。

 > https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sutil/oracle-original-import-utility.html#GUID-83111A9F-A2FC-4DC0-83BB-EDA398BBD4E0
 > If the import job is run by a user with the DBA role, and not all objects can be re-created by user SYSTEM,
 > then the following warning message is written to the log file:
 > IMP-00403:
 > Warning: This import generated a separate SQL file "logfilename_sys" which contains DDL that failed due to a privilege issue.
 > The SQL file that is generated contains the failed DDL of objects that could not be re-created by user SYSTEM.
 > To re-create those objects, you must manually execute the failed DDL after the import finishes.

```sh
# 18c環境
imp \'SYS@xxxxxxxx as sysdba\' transport_tablespace=y \
datafiles='/u01/app/oracle/oradata/SJISDB/7676F6B5B0D33571E0534656860A3EB5/datafile/test01.dbf\
,/u01/app/oracle/oradata/SJISDB/7676F6B5B0D33571E0534656860A3EB5/datafile/test02.dbf'\
 file=test_meta.dmp log=imp_test_meta.log

Import: Release 18.0.0.0.0 - Production on Tue Sep 25 06:03:32 2018
Version 18.2.0.0.0

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

Password:

Connected to: Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.2.0.0.0

Export file created by EXPORT:V09.02.00 via conventional path
About to import transportable tablespace(s) metadata...
import done in US7ASCII character set and AL16UTF16 NCHAR character set
import server uses JA16SJIS character set (possible charset conversion)
export client uses JA16SJIS character set (possible charset conversion)
IMP-00403:

Warning: This import generated a separate SQL file "imp_test_meta_sys.sql" which contains DDL that failed due to a privilege issue.

. importing SYS's objects into SYS
. importing SYS's objects into SYS
. importing AYSHIBAT's objects into AYSHIBAT
. . importing table                        "TBL_A"
Import terminated successfully with warnings.

$ ls -la imp_test_meta_sys.sql
-rw-r--r-- 1 oracle oinstall 0 Sep 25 06:03 imp_test_meta_sys.sql ★0バイト
$ cat imp_test_meta_sys.sql
$
```

# 10. インポート結果の確認(18c)

移行先(18c)のPDBに接続してインポート結果を確認します。

```sql
# 18c
CONNECT AYSHIBAT/xxxxxxxx@yyyyyyyy

SHOW CON_NAME;

CON_NAME
------------------------------
PDB01

SELECT COUNT(*) FROM TBL_A;

  COUNT(*)
----------
      1000
```

# 11. 表領域の READ WRITE化(18c)

移行先(18c)のPDBの表領域を READ WRITE にします。

```sql
-- 18c
ALTER TABLESPACE TEST01 READ ONLY;
ALTER TABLESPACE TEST02 READ ONLY;

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

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

# 12. まとめ

9iR2環境の表領域を18c環境にTTSで移行できたで！彡(ﾟ)(ﾟ)

両バージョンの年月差は実に16年(2002年 vs 2018年)、
バージョンは2倍、威力は100倍、16年の時を経て移行できるTTS最高や！彡(^)(^)

# 13. 参考情報

マニュアルとサポートドキュメントも参照するんやで彡(ﾟ)(ﾟ)

 > Oracle9i Database Release 2 プラットフォーム共通 ドキュメント
 > https://www.oracle.com/technetwork/jp/content/general-082543-ja.html#db
 
 > Oracle9i データベース管理者ガイド リリース2（9.2）
 > 部品番号：J06242-01
 > http://otndnld.oracle.co.jp/document/oracle9i/920/generic/server/J06242-01.pdf
 > データベース間での表領域のトランスポート（11-34）
 > 
 > MOSドキュメント：トランスポータブル表領域移行手順(KROWN:27536) (ドキュメントID 1709003.1)
 > 
 > MOSドキュメント：IMP-00403 "Warning: This import generated a separate SQL file" Using 12.2 imp Command (ドキュメントID 2298963.1)
 > 
 > MOSドキュメント：異なるバージョンのデータベース間でExport/Importを実行する方法(KROWN:45271) (ドキュメントID 1715793.1)