Refreshable Clone PDB を試す（Oracle Database 21c）

# Refreshable Clone PDB とは？
  Oracle Database 12c Release 2 (12.2) 以降の環境ではリモート・インスタンス上で実行されている PDB をローカル環境にコピー（クローン）することができます。クローンは異なるデータベース・バージョン間でも実行できるため、データベースのバージョンアップの手段としても用いることができます。
　コピー元の変更情報（REDO）をコピー先に適用することでリモート環境と同期をとる構成を Refreshable Clone PDB と呼びます。PDB のリフレッシュは手動で行うことも定期的に行うこともできます。本記事では Oracle Database 19c 上のプラガブル・データベース PDB1 を、Oracle Database 21c 上の O19APDB1 としてクローンし、定期的にリフレッシュする環境を作成します。

# DATABASE LINK の作成
  Refreshable Clone PDB のデータ転送はパブリック・データベース・リンク経由で行います。このためクローン先（DESTINATION / Oracle Database 21c）の CDB でパブリック・データベース・リンクを作成します。
　クローン元（SOURCE / Oracle Database 19c）のデータベースにリモート・インスタンスからのデータベース・リンク接続用のユーザーを作成します。このユーザーには CREATE PULAGGABLE DATABASE システム権限と、CREATE SESSION システム権限が必要です。

```SQL:データベース・リンク接続用ユーザーの作成（クローン元で実行）
SQL> CREATE USER C##LINKUSER IDENTIFIED BY <Password> DEFAULT TABLESPACE SYSAUX TEMPORARY TABLESPACE TEMP;

ユーザーが作成されました。

SQL> GRANT CREATE PLUGGABLE DATABASE,CREATE SESSION TO C##LINKUSER1;

権限付与が成功しました。
```

次にクローン先のデータベース（Oracle Database 21c）からクローン元の CDB （またはクローンを実行する PDB / Oracle Database 19c）へ向けてデータベース・リンクを作成します。

```SQL:パブリック・データベース・リンクの作成（クローン先で実行）
SQL> CREATE PUBLIC DATABASE LINK refresh_link CONNECT TO C##LINKUSER IDENTIFIED BY <Password> USING 'dbsvr19c:1521/O19A';

データベース・リンクが作成されました。

SQL> SELECT * FROM dual@refresh_link;

D
-
X
```

# クローンの実行
データベース・リンクを使ってクローンを実行します。非 ASM 環境では FILE_NAME_CONVERT 句を使ってデータファイルのパスを変換します。
下記の例では Oracle Database 19c 上の PDB1 を Oracle Database 21c 上の O19APDB1 へクローンを実行し、30 分間隔で PDB の同期を行います。

```SQL: PDB のクローン実行（クローン先で実行 / Oracle Database 21c）
SQL> CREATE PLUGGABLE DATABASE O19APDB1 FROM PDB1@refresh_link REFRESH MODE EVERY 30 MINUTES FILE_NAME_CONVERT=('/u01/app/oracle/oradata/O19A/pdb1', '/u01/app/oracle/oradata/O21A/O19APDB1');

プラガブル・データベースが作成されました。
```

クローンを実行した PDB の情報を確認します。DBA_PDBS ビューにクローン元の PDB 名、クローンに使用したデータベース・リンク名を表示します。

```SQL: PDB の情報（クローン先で実行  / Oracle Database 21c）
SQL> SELECT PDB_NAME,SOURCE_PDB_NAME,SOURCE_DB_LINK FROM DBA_PDBS WHERE PDB_NAME='O19APDB1';

PDB_NAME   SOURCE_PDB SOURCE_DB_LINK
---------- ---------- --------------------
O19APDB1   PDB1       REFRESH_LINK
```

コピー元の PDB は OPEN 状態になっている必要があります。MOUNTED 状態の場合、以下のエラーが発生します。

```SQL: MOUNTED 状態の PDB クローン
SQL> CREATE PLUGGABLE DATABASE O19APDB1 FROM PDB1@refresh_link REFRESH MODE EVERY 30 MINUTES FILE_NAME_CONVERT=('/u01/app/oracle/oradata/O19A/pdb1', '/u01/app/oracle/oradata/O21A/O19APDB1');
CREATE PLUGGABLE DATABASE O19APDB1 FROM PDB1@refresh_link REFRESH MODE EVERY 30 MINUTES FILE_NAME_CONVERT=('/u01/app/oracle/oradata/O19A/pdb1', '/u01/app/oracle/oradata/O21A/O19APDB1')
*
行1でエラーが発生しました。:
ORA-17628: Oracleエラー65036がリモートOracleサーバーから返されました ORA-65036:
プラガブル・データベースは必要なモードでオープンされていません
```

# 定期実行ジョブの確認
定期的に実行される同期処理は Scheduler Job として作成されるため DBA_SCHEDULER_JOBS ビューで確認できます。ジョブ名は「{コピー先 PDB 名}_{数値}_REFRESH」になります。
ジョブ定義（JOB_ACTION）を確認すると、「alter pluggable database refresh」文を定期的に実行していることがわかります。

```SQL: 定期実行ジョブの確認（クローン先で実行）
SQL> SELECT owner, job_name FROM dba_scheduler_jobs where job_name LIKE 'O19A%';

OWNER      JOB_NAME
---------- ------------------------------
SYS        O19APDB1_983169010_REFRESH 
```

DBA_SCHEDULER_JOBS ビューの主な列値は以下の通りです。

|列名|値|備考|
|:---|:---|:---|
|OWNER|CLONE実行ユーザー||
|JOB_NAME|{元PDB}_{数値}_REFRESH||
|JOB_STYLE|REGULAR||
|JOB_TYPE|PLSQL_BLOCK||
|SCHEDULE_TYPE|CALENDAR||
|JOB_ACTION|下記PL/SQLブロック||
|REPEAT_INTERVAL|FREQ = MINUTELY; INTERVAL = 30|30 分間隔の場合|
|JOB_CLASS|DEFAULT_JOB_CLASS||
|JOB_PRIORITY|3||
|STOP_ON_WINDOW_CLOSE|FALSE||
|SYSTEM|TRUE||
|JOB_WEIGHT|1||
|COMMENT|{クローン先 PDB 名} refresh||

```SQL: JOB_ACTION 列の値
declare cur integer := sys.dbms_sql.open_cursor(security_level => 2);      
begin                                                                          
	sys.dbms_sql.parse(c=> cur,statement  => 'alter pluggable database refresh',
         language_flag => sys.dbms_sql.native,
          container     => 'O19APDB1');                                
	sys.dbms_sql.close_cursor(c=>cur);                                          
end;
```

# 手動リフレッシュ
定期リフレッシュされる PDB は手動でリフレッシュすることもできます。

```SQL: 手動リフレッシュ（クローン先で実行）
SQL> ALTER PLUGGABLE DATABASE O19APDB1 REFRESH;

プラガブル・データベースが変更されました。
```

リフレッシュ時にはクローン先のアラートファイルに以下のログが出力されます。

```: アラートファイル（日時を省略）
alter pluggable database o19apdb1 refresh
Recovering pdb-4099 from SCN 25233358 to SCN 25233399 trc /u01/app/oracle/diag/rdbms/o21a/O21A/trace/O21A_ora_8635.trc
O19APDB1(7):Media Recovery Start
O19APDB1(7):Serial Media Recovery started
O19APDB1(7):max_pdb is 7
O19APDB1(7):Media Recovery Log /u01/app/oracle/admin/O19A/archive/parlog_1_83_63d8b894_1080569267.arc
O19APDB1(7):Incomplete Recovery applied until change 25233399 time
O19APDB1(7):.... (PID:8635): Media Recovery Complete [dbsdrv.c:15172]
Completed: alter pluggable database o19apdb1 refresh
```

# PDB のオープン
　本文書の環境はクローン元とクローン先の Oracle Database はバージョンが異なります。このため、PDB をオープンするためにはクローン先データベースのバージョンアップ処理が必要です。
　まずリフレッシュ・モードを停止します。Job Scheduler ジョブは自動的に削除されます。

```SQL: リフレッシュの停止
SQL>  ALTER PLUGGABLE DATABASE O19APDB1 REFRESH MODE NONE;

プラガブル・データベースが変更されました。

SQL> SELECT owner, job_name FROM dba_scheduler_jobs WHERE job_name LIKE 'O19A%';

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

次に PDB を UPGRADE モードで OPEN し、dbupgrade コマンドで PDB のバージョンアップ処理を行います。

```SQL: UPGRADE モードでオープン
SQL> ALTER PLUGGABLE DATABASE O19APDB1 OPEN UPGRADE;

プラガブル・データベースが変更されました。
```

```SHELL: dbupgrade コマンドの実行
$ dbupgrade -d $ORACLE_HOME/rdbms/admin -c O19APDB1 -l /home/oracle/log

Argument list for [/u01/app/oracle/product/21.0.0/dbhome_1/rdbms/admin/catctl.pl]
For Oracle internal use only A = 0
Run in                       c = O19APDB1
Do not run in                C = 0
Input Directory              d = /u01/app/oracle/product/21.0.0/dbhome_1/rdbms/admin
Echo OFF                     e = 1
... 途中省略 ...
Grand Total Time: 459s [O19APDB1]

 LOG FILES: (/home/oracle/log/catupgrdo19apdb1*.log)

Upgrade Summary Report Located in:
/home/oracle/log/upg_summary.log

     Time: 464s For PDB(s)

Grand Total Time: 464s

 LOG FILES: (/home/oracle/log/catupgrd*.log)

Grand Total Upgrade Time:    [0d:0h:7m:44s]
```

その後、PDB を再度 OPEN すれば移行は完了です。初期化パラメーターは移行されないため、クローン実行後に設定を行います。

Author: Noriyoshi Shinoda / Date: August 30, 2024