【ORACLE MASTER Gold DBA 2019】アプリケーションコンテナについて①

# はじめに
この記事は、1Z0-083: Oracle Database Administration II試験の範囲となっている、アプリケーションコンテナ分野についての概要をまとめたものです。試験対策に重きを置いている関係上、実務上重要な情報が省略されている場合があります。また、内容を新体系試験範囲と翔泳社の12c Advanced Administration試験参考書との差分に絞っています。

## この記事が対応している分野
- アプリケーションPDBの管理
 - アプリケーション・ルートとアプリケーション・シードの目的の説明
 - アプリケーションPDBの定義および作成
 - アプリケーションのインストール、アップグレードおよびパッチ適用
 - アプリケーションPDBの作成および管理

詳細は省いているところもある為、公式ドキュメントとのクロスリファレンスを強くお勧めします。

## 続編が対応している分野
https://qiita.com/arucarap/items/91abd3abf9c1e1dc317f

- アプリケーションPDBの管理
 - PDBおよびアプリケーション・コンテナのクローニング
 - PDBおよびアプリケーション・コンテナを使用したプラグ操作とアンプラグ操作
 - ローカルUNDOモードと共有UNDOモードの比較
- マルチテナント・データベースのセキュリティの管理
 - PDBロックダウン・プロファイルの管理
 - アプリケーション・コンテナでの他のタイプのポリシーの管理

# アプリケーションコンテナとは
アプリケーションコンテナはコンテナデータベース（CDB）のコンポーネントであり、1つ以上のアプリケーションバックエンドのデータやメタデータが格納されています。プラガブルデータベース（PDB）でありながら、CDBのような性質も持っているのが特徴です。アプリケーションコンテナはCDBに接続して利用されるPDBの一種ですが、アプリケーションコンテナ自体にも複数のPDB（アプリケーションシード、アプリケーションPDBおよびプロキシPDB）を含むことができます。

## アプリケーションコンテナの利点
アプリケーションルートにデータやメタデータを格納すると、全てのアプリケーションPDBで共有できます。マスターアプリケーションの定義がアプリケーションルートに保持されることで、アプリケーションのアップグレード時に、一部、または全てのアプリケーションPDBに対して変更を伝播できます。通常のPDBのように、全てのアプリケーションPDBをアプリケーションシードを用いて迅速に作成したり、アプリケーションPDBをアプリケーションルートから切断してから、新しいOracle Databaseリリースのアプリケーションルートに再接続したりすることも可能です。

## アプリケーションルートの概要
アプリケーションルートは、アプリケーションPDBに対してはCDB\$ROOTのように振舞います。しかしながら、**アプリケーション共通オブジェクト**と呼ばれるユーザ作成共通オブジェクトを格納できる点で、CDB\$ROOTや標準PDBのいずれとも異なります。アプリケーション共通オブジェクトはCDB\$ROOT、他のアプリケーションルート、およびアプリケーションルートに属さないPDBには表示されません。
アプリケーションルートは、CDB\$ROOTに接続し、`CREATE PLUGGABLE DATABASE ac_name AS APPLICATION CONTAINER`コマンドを実行することで作成できます。

## アプリケーションPDBの概要
アプリケーションPDBはアプリケーションコンテナ内に存在するPDBのことです。複数のアプリケーションコンテナに属すことはできません。また、アプリケーションPDBはPDBですから、必然的にCDB\$ROOTにも属します。
アプリケーションPDBは、アプリケーションルートに接続し、`CREATE PLUGGABLE DATABASE`コマンドを実行することで作成できます。

## アプリケーションシードの概要
アプリケーションシードは、アプリケーションコンテナ内にゼロまたは一つ含まれる、**オプションの**ユーザー作成PDBです。
アプリケーションシードはPDB\$SEEDがCDB内で果たす役割と同じ役割を果たします。アプリケーションシード名は常に*application_container_name*\$SEEDとなり、変更はできません。
なお、アプリケーションシードを含まないアプリケーションコンテナでアプリケーションPDBを新規作成する場合、アプリケーションPDBは**PDB\$SEEDを使用**して作成されます。
アプリケーションシードを作成するには、`CREATE PLUGGABLE DATABASE AS SEED`文を実行します。データベース名を指定しないことに注意してください。

# アプリケーション共通オブジェクト
アプリケーション共通オブジェクトは、アプリケーションルートのアプリケーション内で作成される共通オブジェクトです。アプリケーション共通オブジェクトに対する問合せでは、現在のコンテナではないコンテナからデータを返すことができます。共通オブジェクトはデータリンク[^1]またはメタデータリンクされています。それら両方の特徴を兼ね備えた拡張データリンクアプリケーションオブジェクトも存在します。
アプリケーション共通オブジェクトを作成または変更できるのは、以降説明する、アプリケーションメンテナンスの一環である場合のみです。
オブジェクトの共有は次の方法で指定できます。

[^1]: データリンクは、Oracle Database 12c R1では**オブジェクト・リンク**と呼ばれていました。

- `DEFAULT_SHARING`初期化パラメータ

ルートで作成された、サポート対象タイプの全てのデータベースオブジェクトに対するデフォルト共有属性を設定できます。指定できる値は`METADATA`（デフォルト）、`DATA`、`EXTENDED DATA`および`NONE`です。

- `SHARING`句

この句は`CREATE`文で指定します。この設定はDEFAULT_SHARING初期化パラメータよりも優先されます。指定できる値はDEFAULT_SHARING初期化パラメータと同じです。

## データリンク共通オブジェクト
データリンク共通オブジェクトの場合、アプリケーションPDBは単一のデータのセットを共有します。例えばアプリケーションコンテナのアプリケーションがデータリンクされた表を含む場合、その表の行はアプリケーションルート内の表のみに格納されますが、アプリケーションコンテナ内の全てのアプリケーションPDBで表示することが出来ます。

## メタデータリンク共通オブジェクト
メタデータリンク共通オブジェクトの場合、アプリケーションPDBはメタデータのみを共有し、異なるデータのセットを持ちます。例えばメタデータリンクされた表はあらゆるアプリケーションPDBで同じ定義を持ちますが、行データ自体はPDBに固有です。
また、共通ユーザーがアプリケーションルートから`CONTAINERS`句を指定した問い合わせを発行することで、コンテナ内に含まれる全てのアプリケーションPDBに対して表やビューを問い合わせることが出来ます。このとき、表やビューは自分のスキーマやアプリケーションルート、および全てのアプリケーションPDBに存在している必要があります。
アプリケーションルートから、メタデータリンクされた表の構造が変更された場合、この変更は各アプリケーションPDBに伝播されます。ただし、アプリケーションPDBからメタデータリンクされた表の構造を変更することは、たとえそのアプリケーションPDB内のみの変更に留めたい場合であってもできません。メタデータリンク共通オブジェクトの変更を行いたい場合は、必ずアプリケーションルートに接続します。

## 拡張データリンクオブジェクト
拡張データリンクオブジェクトでは、各アプリケーションPDBはアプリケーションルートの共通データを共有すると同時に、独自の固有データを作成することができます。拡張データリンクはデータリンクとメタデータリンクの特徴を合成させたものといえます。
なお、拡張データリンクオブジェクトにすることができるのは、表およびビューのみです。

# アプリケーションメンテナンス
ここでのアプリケーションメンテナンスは、アプリケーションのインストール、アップグレードまたはパッチ適用を指します。アプリケーションには名前およびバージョン番号が必要です。
全てのメンテナンス作業で、次のステップを実行します。

1. 読取り/書込みオープンされたアプリケーションルートで`ALTER PLUGGABLE DATABASE APPLICATION`文を、`BEGIN INSTALL`句、`BEGIN UPGRADE`句または`BEGIN PATCH`句とともに実行することで開始します。`ALTER PLUGGABLE DATABASE`システム権限が必要です。
1. アプリケーションメンテナンスの文を実行します。
1. `ALTER PLUGGABLE DATABASE APPLICATION`文を`END INSTALL`句、`END UPGRADE`句または`END PATCH`句とともに実行することで終了します。

## アプリケーションのインストール
アプリケーションのインストールにより、ユーザーアカウント、表およびPL/SQLパッケージが作成されます。アプリケーションをインストールするには、`ALTER PLUGGABLE DATABASE APPLICATION`文に次の項目を指定します。

- アプリケーション名
- アプリケーションのバージョン番号

```
-- 実行例:
ALTER PLUGGABLE DATABASE APPLICATION app_name BEGIN INSTALL '1.0';
```

## アプリケーションのアップグレード
アプリケーションのアップグレードは、インストールされたアプリケーションへの大規模な変更です。アプリケーションをアップグレードする場合、CDBは**ローカルUNDOモードである必要**があります。アプリケーションをアップグレードするには、`ALTER PLUGGABLE DATABASE APPLICATION`文で次の項目を指定する必要があります。

- アプリケーション名
- 古いアプリケーションのバージョン番号
- 新規のアプリケーションのバージョン番号

```
-- 実行例:
ALTER PLUGGABLE DATABASE APPLICATION app_name BEGIN UPGRADE '1.0' to '2.0';
```

アプリケーションのアップグレード中、アプリケーションは引き続き使用可能です。アップグレード中、自動的にアプリケーションルートがクローニングされ、アプリケーションPDBがアプリケーションルートクローンに示されます。クローンは読取り専用モードです。
**アップグレード終了後も、アプリケーションPDBは依然としてアプリケーションルートクローンを示しており**、元のアプリケーションルートが新規バージョンになります。この仕組みにより、異なるアプリケーションPDBで異なるバージョンのアプリケーションを使用することができます。
アプリケーションPDBをアップグレード済みのアプリケーションルートと同期化するには、`ALTER PLUGGABLE DATABASE APPLICATION app_name SYNC`文を発行する必要があります。全てのアプリケーションPDBを一括で同期化したい場合には、`ALL SYNC`句を指定することもできます。

## アプリケーションのパッチ
アプリケーションパッチは、アプリケーションの小規模な変更です。アップグレードと同様に、作業後にはパッチを適用したい全てのアプリケーションPDBを同期化する必要があります。
一般にアプリケーションのパッチ適用では破壊的な操作は許可されません。例えば、`DROP`文や、列の削除またはデータ型の変更を行う`ALTER TABLE`文をパッチに含めることはできません。パッチ適用プロセスでエラーが発生する場合、代わりにアプリケーションのアップグレードを実行します。
なお、パッチ適用ではアップグレードと異なり、アプリケーションルートクローンが作成されません。
アプリケーションのパッチを適用するには、`ALTER PLUGGABLE DATABASE APPLICATION`文にアプリケーション名とパッチ番号を指定します。オプションで、アプリケーション最小バージョンを指定することもできます。

```
-- 実行例:
ALTER PLUGGABLE DATABASE APPLICATION app_name BEGIN PATCH 101 MINIMUM VERSION '1.0';
```

# 既存のアプリケーションの移行
通常のPDBにインストールされているアプリケーションを、アプリケーションルートまたはアプリケーションPDBのいずれかに移行することができます。

## 既存アプリケーションのアプリケーションPDBへの移行
既存アプリケーションをアプリケーションルートに移行した後で、既存のPDBを使用してアプリケーションPDBを作成できます。PDBは、アプリケーションで使用する全てのアプリケーション共通オブジェクトを含む必要があります。

# 暗黙的に作成されるアプリケーション
ユーザー作成アプリケーション以外に、アプリケーションコンテナには暗黙的に作成されるアプリケーションも含まれます。
`ALTER PLUGGABLE DATABASE BEGIN`文を最初に使用せずに、アプリケーション共通ユーザー操作が`CONTAINER=ALL`句によって発行されると、アプリケーションルートでアプリケーションが暗黙的に作成されます。アプリケーション共通ユーザー操作には、共通ユーザーの作成や変更などの操作が含まれます。暗黙的アプリケーションには、APP\$で始まる一意な名前が自動的に付けられます。暗黙的アプリケーションは、アプリケーションルートが初めて開かれたときに作成されます。
アプリケーションPDB内の暗黙的アプリケーションを同期したい場合、アプリケーション名を直接指定するか、アプリケーション名に`APP$CON`を指定できます。`APP$CON`を指定して暗黙的アプリケーションを同期する場合、そのアプリケーションPDB内の全ての暗黙的アプリケーションが同期されます。

```
-- 暗黙的アプリケーションを同期する操作の実行例:
ALTER PLUGGABLE DATABASE APPLICATION APP$CON SYNC;
```

# プロキシPDBとしてのPDBの作成
プロキシPDBは、参照先PDBと呼ばれるリモートCDB内の別のPDBへのアクセスを提供します。プロキシPDBで実行のために発行されたSQL文は、参照先PDB内で実行されます。プロキシPDBは一般的に、**アプリケーションルートレプリカ**を参照する用途で使用されます。
複数のCDBに同じアプリケーション定義がある場合、マスターアプリケーションルートのアプリケーションコンテナで、異なるCDB内のアプリケーションルートを参照するプロキシPDBを作成できます。インストールスクリプトをマスタールートで実行することで、他のCDB内のアプリケーションルートがマスターアプリケーションルートのレプリカになります。アプリケーションルートレプリカが構成され、固有のアプリケーションPDBを持つ場合、マスターアプリケーションルートで発行された`CONTAINERS`句を含む問い合わせは、アプリケーションルートレプリカおよびレプリカに接続しているオープンされたアプリケーションPDBからの結果を表示できます。
プロキシPDBを作成するには、参照先PDBへのデータベースリンクを指定した`FROM`句および`AS PROXY`句とともに`CREATE PLUGGABLE DATABASE`文を使用します。

```
-- 実行例:
CREATE PLUGGABLE DATABASE pdb1 AS PROXY FROM pdb1@pdb1_link;
```

なお、参照先PDBを含むCDBはローカルUNDOモードかつ`ARCHIVELOG`モードである必要があります。また、データベースリンクでリモートCDBのルートに接続するユーザーは共通ユーザーである必要があります。

# 付録: 練習問題
自作の練習問題です。

### アプリケーション・コンテナについて正しい記述はどれですか。

- A) アプリケーション・ルートを作成するには、`CREATE DATABASE`権限を持ったユーザーでCDB\$ROOTに接続し、`AS APPLICATION CONTAINER`オプションを付与した`CREATE DATABASE`文を実行する。
- B) アプリケーションPDBとは、CDB\$ROOTのかわりにアプリケーション・ルートに接続したPDBのことをいう。
- C) アプリケーション・シードの名前は、アプリケーション・コンテナの名前に依存する。
- D) リモートCDB内のアプリケーションPDBへアクセスできるようにするためには、リモートCDBにプロキシPDBを構成する必要がある。

<details><summary>解答と解説</summary><div>

解答: C

A: 誤りです。アプリケーションルートを作成するには、`CREATE DATABASE`文ではなく`CREATE PLUGGABLE DATABASE`文を実行します。

B: 誤りです。アプリケーションPDBはCDB\$ROOTにも所属します。

C: **正解です。**アプリケーションシード名は*アプリケーションコンテナ名*\$SEEDとなり、変更はできません。

D: 誤りです。ローカルCDBにプロキシPDBとデータベースリンクを、リモートCDBにアプリケーションルートレプリカを構成します。

</div>

### アプリケーション共通オブジェクトについて正しい記述はどれですか。

- A) データリンク・アプリケーション共通オブジェクトがプロキシPDBを使用してアプリケーション・ルート・レプリカを同期する構成の一部である場合、DMLによる変更はアプリケーション・ルート・レプリカに自動的に伝播されない。
- B) `DEFAULT_SHARING`初期化パラメータのデフォルト値は`NONE`である。
- C) 拡張データリンク・共通オブジェクトに設定できるオブジェクトは、表、ビュー、およびシノニムのみである。
- D) 現在アプリケーション・ルートに接続している場合、アプリケーションPDBに固有で含まれる、拡張データリンク・アプリケーション共通オブジェクトのデータを問い合わせることはできない。

<details><summary>解答と解説</summary><div>

解答: A

A: **正解です**。データリンク共通オブジェクトや拡張データリンク共通オブジェクトへのDML操作は、リモートのアプリケーションルートレプリカに自動的に伝播されません。DML操作を伝播したい場合、アプリケーションのメンテナンス時に実行する必要があります。

B: 誤りです。`DEFAULT_SHARING`初期化パラメータのデフォルト値は`METADATA`です。

C: 誤りです。拡張データリンク共通オブジェクトに設定できるオブジェクトは、表、ビューのみです。シノニムを拡張データリンク共通オブジェクトに設定することは出来ません。

D: 誤りです。アプリケーション・ルートからは、アプリケーションPDBに固有で含まれる、メタデータリンクアプリケーション共通オブジェクトや拡張データリンクアプリケーション共通オブジェクトのデータを問い合わせることができます。ただし、CDB\$ROOTからアプリケーション共通オブジェクトを問い合わせることはできません。

</div>

### アプリケーション・コンテナにおける、アプリケーションのメンテナンスについて正しい記述はどれですか（2つ選択してください）。

- A) アプリケーションにパッチを適用した場合、同じアプリケーション・コンテナ内に存在するすべてのアプリケーションPDBは、アプリケーション・ルートのアプリケーションと自動的に同期され、変更が伝播される。
- B) アプリケーションにパッチを適用するプロセスで、「アプリケーション・パッチで操作がサポートされていません」というエラーが出た場合には、パッチ適用のかわりにアプリケーションのアップグレードを行うことを検討する。
- C) アプリケーションをアップグレードした場合、アップグレードに関連するアプリケーションの変更は、同じアプリケーション・コンテナ内に存在するすべてのアプリケーションPDBに伝播される。
- D) アプリケーションPDBにおいて、`ALTER PLUGGABLE DATABASE APPLICATION APP$CON SYNC;`を実行すると、そのアプリケーションPDB内に存在するすべての暗黙的に作成されたアプリケーションが、アプリケーション・ルート内の最新のアプリケーション変更と同期される。

<details><summary>解答と解説</summary><div>

解答: B, D

A: 誤りです。アプリケーションルートとの同期は自動的には行われません。同期するには`ALTER PLUGGABLE DATABASE APPLICATION app_name SYNC`文を実行する必要があります。

B: **正解です。**破壊的な操作はパッチ適用では許可されません。破壊的な操作を行いたい場合はパッチ適用の代わりにアップグレードを行います。

C: 誤りです。アップグレードやパッチ適用の変更が伝播されるのは、アプリケーションルート内のアプリケーションと同期されるアプリケーションPDBだけです。それ以外のアプリケーションPDBは、旧バージョンのアプリケーションを使用し続けることができます。

D: **正解です。**アプリケーション名に`APP$CON`を指定すると、アプリケーションPDBに存在する全ての暗黙的アプリケーションがアプリケーションルート内の最新の変更と同期されます。なお、全てのアプリケーションをアプリケーションルートと同期する場合には`ALL SYNC`句を使用します。

</div>

# 続編
https://qiita.com/arucarap/items/91abd3abf9c1e1dc317f

# 参考
[19c Multitenant管理者ガイド](https://docs.oracle.com/cd/F19136_01/multi/index.html)