Oracle Database:リモート・クローンで文字コード異なるPDBを混在させてみてみた

JA16SJISデータベースから別のAL32UTF8データベースにデータベース・リンクを介してPDBをリモート・クローンしてみてみます。
手順は通常のリモート・クローンと同じで、文字コード異なる複数のPDBを１つのCDBへ混在させることができます。
Oracle Cloud infrastructure(OCI)のDatabase Cloud Serviceでは、表領域暗号化Transparent Data Encryption(TDE)はデフォルトで有効になっています。
ということで、Oracle Database 18cでは、KEYSTORE IDENTIFIED BY句を追加したCREATE PLUGGABLE DATABASE文によって、暗号化データを含むPDBをリモートからクローニングできます。 

    ・Remote Cloning手順概要
        1. Target DB :Source DB接続 Database Link設定
        2. Target DB :Source PDB クローン実行
        3. Target DB :クローンPDB 起動

・リモートクローン要件参考: 
　- Advanced Securityガイド：[統一モードで、暗号化データを含むPDBのリモート・クローニングを2つのCDB間で実行する](https://docs.oracle.com/cd/E96517_01/asoag/managing-keystores-encryption-keys-in-united-mode.html#GUID-2B2E9E7D-10E0-4D3E-B466-4767AC3D81C1)
　- グローバリゼーション・サポート・ガイド：[PDB候補がCDBルートに直接プラグインされる場合](https://docs.oracle.com/cd/E82638_01/nlspg/choosing-character-set.html#GUID-09777A99-B7DD-4695-9B2B-278122131000)


#■構成
<img width="711" alt="構成.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109087/4df70f32-ec3a-fcd7-e0d2-9313b746c6c0.png">




#■環境事前確認

##●環境変数確認
以下が設定されていることを確認

・Target DB:sjis2db

```shell-session
[oracle@sjis2db ~]$ env | grep ORA
    ORACLE_UNQNAME=sjis2db
    ORACLE_SID=sjis2db
    ORACLE_HOME=/u01/app/oracle/product/18.0.0.0/dbhome_1
```


・Source DB:UTF8PDB

```shell-session
[oracle@utf8db ~]$ env | grep ORA
    ORACLE_UNQNAME=UTF8PDB
    ORACLE_SID=UTF8PDB
    ORACLE_HOME=/u01/app/oracle/product/18.0.0.0/dbhome_1
```



##●Walletパス確認

・Target DB:sjis2db

```shell-session
[oracle@sjis2db admin]$ cat $ORACLE_HOME/network/admin/sqlnet.ora
    ENCRYPTION_WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/opt/oracle/dcs/commonstore/wallets/tde/$ORACLE_UNQNAME)))
    ・・・
```


・Source DB:UTF8DB

```shell-session
[oracle@sjis2db ~]$ cat $ORACLE_HOME/network/admin/sqlnet.ora
    ENCRYPTION_WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/opt/oracle/dcs/commonstore/wallets/tde/$ORACLE_UNQNAME)))
    ・・・
```


##●PDB文字コード確認

・Target DB:sjis2pdb

```shell-session
[oracle@sjis2db ~]$ sqlplus / as sysdba

SQL*Plus: Release 18.0.0.0.0 - Production on Tue Jul 23 09:24:00 2019
    Version 18.6.0.0.0

    Copyright (c) 1982, 2018, Oracle.  All rights reserved.

    Connected to:
    Oracle Database 18c EE High Perf Release 18.0.0.0.0 - Production
    Version 18.6.0.0.0

SQL> alter session set container=SJIS2PDB;
    Session altered.

SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';

    VALUE
    ------------
    JA16SJIS
```


・Source DB:UTF8PDB

```shell-session
[oracle@utf8db ~]$ sqlplus / as sysdba

SQL*Plus: Release 18.0.0.0.0 - Production on Tue Jul 23 09:25:19 2019
    Version 18.6.0.0.0

    Copyright (c) 1982, 2018, Oracle.  All rights reserved.

    Connected to:
    Oracle Database 18c EE High Perf Release 18.0.0.0.0 - Production
    Version 18.6.0.0.0

SQL> alter session set container=UTF8PDB;
    Session altered.

SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';

    VALUE
    ------------
    AL32UTF8
```




#■1. Target DB :Source DB接続用Database Link作成
##● Source DB(sjis2db): Database Link接続User作成

```shell-session
[oracle@sjis2db ~]$ sqlplus / as sysdba

SQL> col NAME format a20
SQL> select name, open_mode from v$pdbs;
    NAME		     OPEN_MODE
    -------------------- ----------
    PDB$SEED	     READ ONLY
    SJIS2PDB		 READ WRITE

SQL> alter session set container=SJIS2PDB;
    Session altered.

SQL> create user remote_user_for_clone identified by <user パスワード>;
    User created.

SQL> grant create session,create pluggable database to remote_user_for_clone;
    Grant succeeded.

```

##● Target Databse(utf8db):Database Link設定

###① Source DBでPDBの接続情報確認
Target DBのtnsnames.oraに設定するSERVICE_NAMEをlsnrctlで確認

```shell-session
[oracle@sjis2db ~]$ lsnrctl stat | grep pdb
    Service "sjis2pdb.publicsubnet01.vcnxxxxx.oraclevcn.com" has 1 instance(s).
```

###② tnsnames.ora設定
Target DBのtnsnames.oraにSource PDBの接続情報SJIS2PDBを設定

```shell-session
[oracle@utf8db ~]$ cd $ORACLE_HOME/network/admin
[oracle@utf8db ~]$ vi tnsnames.ora

SJIS2PDB =
    (DESCRIPTION =
        (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.0.10)(PORT = 1521)
        (CONNECT_DATA =
        (SERVER = DEDICATED)
        (SERVICE_NAME = sjis2pdb.publicsubnet01.vcnxxxxx.oraclevcn.com)
        )
    )
```


###③　Database link作成
リモート・クローンの場合、DB_DOMAIN異なるので、リモート側のDOMAIN含めた名前で作成

```shell-session
SQL> create database link sjis2pdb.publicsubnet01.vcnxxxxx.oraclevcn.com connect to remote_user_for_clone identified by <Database Linkパスワード> using 'SJIS2PDB_NRT1RK';
    Database link created.
```

###④ Database link接続確認

```shell-session
SQL> select * from dual@sjis2pdb.publicsubnet01.vcnxxxxx.oraclevcn.com;
    D
    -
    X
```


#■2. Target DB :Source PDB クローン実行

##● リモート・クローン実行

```shell-session
SQL> create pluggable database Clone_SJIS2PDB from SJIS2PDB@sjis2pdb.publicsubnet01.vcnxxxxx.oraclevcn.com KEYSTORE IDENTIFIED BY <Database Linkパスワード>;
    Pluggable database created.
```


##● リモート・クローンPDB作成確認

```shell-session
SQL> col NAME format a20
SQL> select name, open_mode from v$pdbs;

    NAME		     OPEN_MODE
    -------------------- ----------
    PDB$SEED	     READ ONLY
    UTF8PDB		     READ WRITE
    CLONE_SJIS2PDB	     MOUNTED
```


#■3. Target DB :クローンPDB 起動

```shell-session
SQL>  alter pluggable database CLONE_SJIS2PDB open;

    Pluggable database altered.

SQL> select name, open_mode from v$pdbs;

    NAME		     OPEN_MODE
    -------------------- ----------
    PDB$SEED	     READ ONLY
    UTF8PDB		     READ WRITE
    CLONE_SJIS2PDB	     READ WRITE
```


#■4.PDB文字コード確認

① CDB$ROOT文字コード確認

```shell-session
SQL> alter session set container=CDB$ROOT;
    Session altered.

SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';

    VALUE
    -------------
    AL32UTF8
```

②　UTF8PDB文字コード確認

```shell-session
SQL> alter session set container=UTF8PDB;
    Session altered.

SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';
    VALUE
    -------------
    AL32UTF8
```


③ CLONE_SJIS2PDB文字コード確認

```shell-session
SQL> alter session set container=CLONE_SJIS2PDB;
SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';
    VALUE
    -------------
    JA16SJIS
```

#■参考
 **・SQL言語リファレンス**
　　- [CREATE PLUGGABLE DATABASE](https://docs.oracle.com/cd/F19136_01/sqlrf/CREATE-PLUGGABLE-DATABASE.html#GUID-F2DBA8DD-EEA8-4BB7-A07F-78DC04DB1FFC)
 **・Advanced Securityガイド**
　　- [統一モードで、暗号化データを含むPDBのリモート・クローニングを2つのCDB間で実行する](https://docs.oracle.com/cd/E96517_01/asoag/managing-keystores-encryption-keys-in-united-mode.html#GUID-2B2E9E7D-10E0-4D3E-B466-4767AC3D81C1)
 **・Database グローバリゼーション・サポート・ガイド**
　　- [PDB候補がCDBルートに直接プラグインされる場合](https://docs.oracle.com/cd/E82638_01/nlspg/choosing-character-set.html#GUID-09777A99-B7DD-4695-9B2B-278122131000)
　　- [マルチテナント・コンテナ・データベースのデータベース文字セットの選択](https://docs.oracle.com/cd/F19136_01/nlspg/choosing-character-set.html#GUID-09777A99-B7DD-4695-9B2B-278122131000)