【Oracle Database】Pluggable Database(PDB)を作成する

Oracle Databaseマルチテナント環境において、PDBを作成する手順をメモ程度に示します。

バージョンは19cです。


# はじめに
PDBを作成するといっても方法は様々。[ドキュメント](https://docs.oracle.com/cd/E96517_01/multi/overview-of-pdb-creation.html#GUID-BAD70A3D-0C46-4392-BCC9-B17413A0BA21)によると、以下の手法があるようです。
1. PDBを最初から作成
1. 既存のPDBまたは非CDBをクローニング
1. PDBを異なるCDBに再配置
1. 切断されたPDBをCDBに接続
1. PDBをプロキシPDBとして参照
1. 非CDBからPDBを作成し、PDBをCDBに接続

この記事では「**1. PDBを最初から作成**」にて作成します。作成にあたってはいずれも`CREATE PLUGGABLE DATABASE`文が必要になりますので、権限を確認しておきましょう。

またPDBの作成について、DBA Goldの問題解説記事になりますが以下のサイトも非常に参考になります。
[Gold DBA 2019 Seminar Series 第2回：プラガブル・データベース (PDB) の作成](https://blogs.oracle.com/oraclemaster/post/om-golddba-2019-seminar-2)


# PDBを最初から作成する
新しいPDBを作成するにはPDB$SEEDをクローニングする形で作成します[^1]。
（以下、PDB$SEEDをSEEDと表記します。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761799/815dc312-20b8-b11f-20e5-7627ed201129.png)

OMFが有効化されている場合、OMFは自動的にデータファイルの場所を管理してくれるため、データファイルの場所を明示的に指定する必要はありません。

今回、OMFは無効化されているため、データファイルの場所を指定する必要があります。コマンドとしては以下のようになるのですが、その前にPDB$SEEDのデータファイルがどこにあるかを確認しておきましょう。

```:SEEDからクローニングして新しいPDBを作成
CREATE PLUGGABLE DATABASE pdb_name
ADMIN USER pdb_admin IDENTIFIED BY password
FILE_NAME_CONVERT = ('/path_to_source/', '/path_to_destination/');
```

## 1. PDB$SEEDのデータファイルの位置を確認する
SEEDに移動します。
```
-- SEEDに移動
SQL> alter session set container = PDB$SEED;

Session altered.


-- SEEDに移動できたことを確認
SQL> show con_name

CON_NAME
------------------------------
PDB$SEED
```

SEEDのデータファイルの位置を確認します。念のため`PDB$SEED`のファイルだと確認したかったのでJOINしていますが、ファイルパスを確認するだけであれば2番目のSQLで問題ありません。
```: SEEDのデータファイルのパスを確認する
SELECT dbf.file_name, pdb.name 
FROM cdb_data_files dbf
JOIN v$pdbs pdb ON dbf.con_id = pdb.con_id;
```
<details><summary>上記SQLの結果</summary>

```
"FILE_NAME","NAME"
"/opt/oracle/oradata/ORCLCDB/pdbseed/system01.dbf","PDB$SEED"
"/opt/oracle/oradata/ORCLCDB/pdbseed/sysaux01.dbf","PDB$SEED"
"/opt/oracle/oradata/ORCLCDB/pdbseed/undotbs01.dbf","PDB$SEED"
```
</details>

<br>

```: パスを知るだけであればこれだけでも問題ない
SELECT file_name FROM dba_data_files;
```

<details><summary>上記SQLの結果</summary>

```
"FILE_NAME"
"/opt/oracle/oradata/ORCLCDB/pdbseed/system01.dbf"
"/opt/oracle/oradata/ORCLCDB/pdbseed/sysaux01.dbf"
"/opt/oracle/oradata/ORCLCDB/pdbseed/undotbs01.dbf"
```
</details>


:::note warn
CDBから以下のコマンドでSEEDのデータファイルが見られると思ったのですが、どうやらデフォルトではSEEDは例外的に表示されないようです[^3]。
表示させるには`exclude_seed_cdb_view`パラメータを`true`にする必要があります。[^4]
```
SELECT file_name FROM cdb_data_files
WHERE con_id = (
    SELECT con_id
    FROM v$pdbs
    WHERE name = 'PDB$SEED'
);
```
:::


## 2. PDBを作成

CDBに戻り、1.で得られたパスを引数にPDB「testpdb」を作成します。

```: CDBに戻ったことを確認
SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT
```

```: testpdbを作成
CREATE PLUGGABLE DATABASE testpdb
	ADMIN USER testadmin IDENTIFIED BY Welcome123#
	STORAGE (MAXSIZE 1G)
	PATH_PREFIX = '/opt/oracle/oradata/ORCLCDB/TESTPDB/'
	FILE_NAME_CONVERT = ('/opt/oracle/oradata/ORCLCDB/pdbseed/', '/opt/oracle/oradata/ORCLCDB/TESTPDB/');
```
PATH_PREFIX句はPDB内でのファイルのデフォルトの場所を指定するために使用されるパラメータです。PDBの作成やクローン時に、デフォルトで使用されるディレクトリパスを定義します。

OMFが無効かつFILE_NAME_CONVERT句が指定されていない場合、`PDB_FILE_NAME_CONVERTパラメータ`[^2]によってファイル名が置き換えられます。


## 3. 作成したPDBを確認する

私の環境では15秒ほどでPDBは完成しました。

```: CREATE PLUGGABLE DATABASE文の実行結果
SQL> CREATE PLUGGABLE DATABASE testpdb
  2      ADMIN USER testadmin IDENTIFIED BY Welcome123#
  3      STORAGE (MAXSIZE 1G)
  4      PATH_PREFIX = '/opt/oracle/oradata/ORCLCDB/TESTPDB/'
  5      FILE_NAME_CONVERT = ('/opt/oracle/oradata/ORCLCDB/pdbseed/', '/opt/oracle/oradata/ORCLCDB/TESTPDB/');

Pluggable database created.

Elapsed: 00:00:14.92
```
<br>
マウント状態で作成されていることが確認できます。

```
SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORCLPDB1                       READ WRITE NO
         4 ORCLPDB2                       MOUNTED
         5 TESTPDB                        MOUNTED
```
<br>

データファイルを見に行きましょう。FILE_NAME_CONVERT句で指定したディレクトリに移動します。
```
$ cd /opt/oracle/oradata/ORCLCDB/TESTPDB/
$ ls
sysaux01.dbf  system01.dbf  temp012024-05-08_06-54-06-817-AM.dbf  undotbs01.dbf
```
以下がSEEDのディレクトリですが、上下を見比べてもしっかりクローニングされたことが確認できます。
```: PDB$SEED
$ ls
sysaux01.dbf  system01.dbf  temp012024-05-08_06-54-06-817-AM.dbf  undotbs01.dbf
```

[^1]: https://docs.oracle.com/cd/E96517_01/multi/creating-a-pdb-from-scratch.html#GUID-534B3B1D-0ED7-4828-9CA4-B1757398801F
[^2]: https://docs.oracle.com/cd/F19136_01/refrn/PDB_FILE_NAME_CONVERT.html
[^3]: https://forums.oracle.com/ords/apexds/post/unable-to-find-seed-database-files-in-cdb-data-files-4388
[^4]: https://www.dbi-services.com/blog/12102-cdb-views-are-now-using-containers/