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

# はじめに
この記事は、1Z0-083: Oracle Database Administration II試験の範囲となっている、アプリケーションコンテナ分野についての概要をまとめたものです。拙稿「[アプリケーションコンテナについて①](https://qiita.com/arucarap/items/a55c9621cc54673f4cfe)」の続編にあたります。

## この記事が対応している分野

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

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

# ローカルUNDOモードと共有UNDOモード
ローカルUNDOモードは、12c R2で追加された新機能です。従来のCDBではルートコンテナのみがUNDO表領域を持っていました。これを共有UNDOモードと呼びます。
対してローカルUNDOモードでは、各コンテナそれぞれが独自のUNDO表領域を持ちます。これにより、PDB単位のフラッシュバックデータベースといった機能を利用できるようになります。
UNDOモードの設定はCDB単位で行われます。デフォルトは共有UNDOモードです。

## ローカルUNDOモードの特徴
- *CDBをアップグレードモードでOPEN*し、`CREATE DATABASE`文または`ALTER DATABASE`文で`LOCAL UNDO ON`オプションを指定して設定します。設定変更後はCDBの再起動が必要です。
- UNDO表領域が存在しないPDBには、次回オープン時に自動的にUNDO表領域が作成されます。
- PDB単位でフラッシュバックデータベースができるようになります。MOUNT状態のPDBで`FLASHBACK PLUGGABLE DATABASE`文を実行します。
 - PDBであるため、OPEN時に`ALTER PLUGGABLE DATABASE pdb CLOSE;`を実行することでMOUNT状態にすることができます。
 - **PDBリストアポイント**を利用してフラッシュバックデータベースを実行することもできます。PDBリストアポイントとは、作成したPDBのみで参照・使用できるリストアポイントです。
- ソースPDBを読取り/書込みオープンしたままクローニングできます（ホットクローニング）。
 - ローカルUNDOモードに加え、`ARCHIVELOG`モードである必要があります。
- アプリケーションコンテナのアプリケーションをアップグレードできます。

## 共有UNDOモードの特徴
- CDBをアップグレードモードでOPENし、`CREATE DATABASE`文または`ALTER DATABASE`文で`LOCAL UNDO OFF`オプションを指定して設定します。設定変更後はCDBの再起動が必要です。
- `FLASHBACK PLUGGABLE DATABASE`文を実行すると**Point-in-Timeリカバリ**が行われます。
 - PITRであるため、バックアップや補助データベース用の領域確保が必要です。
 - リカバリ地点にPDBリストアポイントを指定して実行した場合にもPITRが行われます。
- リカバリ地点に**クリーンPDBリストアポイント**を指定した場合には、共有UNDOモードであってもPDBフラッシュバックデータベースを使用できます。

クリーンPDBリストアポイントは、データの読み取り一貫性が取れた時点のリストアポイントです。PDBがクローズされており、未処理のトランザクションが存在しない場合のみに作成することができます。クリーンPDBリストアポイントを利用してフラッシュバックデータベースを行った場合、補助データベースの作成やリストア・リカバリは行われません。
クリーンPDBリストアポイントを作成するには、PDBをクローズした状態で`CREATE CLEAN RESTORE POINT`文を実行します。

# アプリケーションPDBのクローニング
アプリケーションPDBはアプリケーションシード、リモートまたはローカルのPDB、あるいは非CDBからクローニングすることができます。いずれの方法でも、アプリケーションPDBをアプリケーションルートから定義する必要があります。

## アプリケーションシードを利用したクローニング
`CREATE PLUGGABLE DATABASE`文を使用することで、アプリケーションシードからアプリケーションPDBをクローニングすることができます。

## PDBまたは非CDBを利用したクローニング
ソースデータベースを読取り専用オープンした状態で`CREATE PLUGGABLE DATABASE FROM`文を使用することで、PDBや非CDBからアプリケーションPDBをクローニングできます。リモートCDBからPDBをクローニングする場合にはデータベースリンクを使用します。
なお、一定の条件が揃っている場合にはソースデータベースを読取り/書込みオープンしたままクローニングすることもできます。

### PDBを利用したクローニング
ソースPDBが所属するCDBが`ARCHIVELOG`モードかつ**ローカルUNDOモード**の場合、ソースPDBを読取り/書込みオープンしたままクローニングできます。これを**ホットクローニング**と呼びます。
Oracle Database **18c**以降では、DBCAを利用して**ローカルPDBを**クローニングできます。またOracle Database **19c**以降では、DBCAを使用して**リモートPDBを**クローニングできます。

### 非CDBを利用したクローニング
ソースデータベースが`ARCHIVELOG`モードの場合、読取り/書込みオープンしたままクローニングできます。

# アプリケーションコンテナのプラグ操作とアンプラグ操作
アプリケーションコンテナと通常PDBのプラグ操作やアンプラグ操作はよく似ています。切断するPDBはクローズされている必要がある、といった注意事項はおよそ共通です。
以下にアプリケーションコンテナ特有の注意点についてまとめます。

## アプリケーションPDBをアプリケーションコンテナに接続する場合
- 接続するPDBと接続対象アプリケーションコンテナのアプリケーション名およびバージョンは一致する必要があります。
- 接続するPDBと接続対象アプリケーションコンテナの文字セットおよび各国語文字セットは一致する必要があります。
 - 12c R2以降では、CDBのデータベース文字セットが**AL32UTF8**の場合には、各PDBの文字セットおよび各国語文字セットはCDBと異なっていてもかまいません。しかし、アプリケーションコンテナ内の全ての**アプリケーションPDBには、アプリケーションコンテナと同じ文字セットおよび各国語文字セットが必要**です。

## アプリケーションコンテナをCDBから切断する場合
- アプリケーションコンテナにアプリケーションシードやアプリケーションPDBが接続されていない必要があります。

# コンテナマップについて
コンテナマップを使用することで、メタデータリンクオブジェクトのデータをパーティション化できます。アプリケーションルートに対して、コンテナマップが使用されたメタデータリンクオブジェクトを問い合わせると、自動的に適切なアプリケーションPDBからデータが返されます。

# PDBロックダウンプロファイルについて
PDBにおいて、しばしば過剰な権限が存在することがあります。PDBロックダウンプロファイルを使用することで、PDBの操作を制御できます。例えば、特定の`ALTER SYSTEM`文を無効にすることができます。
PDBロックダウンプロファイルは、**ベースプロファイル**や基本プロファイルと呼ばれる、別のプロファイルを元に作成することもできます。また設定次第では、ベースプロファイルが更新されたときにPDBロックダウンプロファイルが自動更新されるように構成できます。

## PDBロックダウンプロファイルの作成と有効化
PDBロックダウンプロファイルを作成するには、最初に`CREATE LOCKDOWN PROFILE`文を使用してプロファイルをCDB$ROOTまたはアプリケーションルートに作成し、その後で`ALTER LOCKDOWN PROFILE`文を使用してそれに制限を加えます。`CREATE LOCKDOWN PROFILE`システム権限が必要です。
`CREATE LOCKDOWN PROFILE`文に`FROM`句または`INCLUDING`句を指定することで、既存のプロファイル（ベースプロファイル）を元にして新しいロックダウンプロファイルを作成できます。`FROM`句を指定して作成する場合、ベースプロファイルへの以降の変更は、新しいプロファイルには影響しません。対して`INCLUDING`句を指定して作成する場合には、ベースプロファイルへの以降の変更を継承します。

PDBロックダウンプロファイルを有効にするには、`ALTER SYSTEM SET PDB_LOCKDOWN = profile_name`文を実行します。プロファイルの変更は即座に有効化されます。再起動の必要はありません。

PDBロックダウンプロファイルを無効化するには、`PDB_LOCKDOWN`を`null`に設定します。
PDBロックダウンプロファイルを削除するには、`DROP LOCKDOWN PROFILE`コマンドを実行します。`DROP LOCKDOWN PROFILE`システム権限があり、CDBまたはアプリケーションルートにログインすることが必要です。

`SYSDBA`管理権限または`ALTER SYSTEM`システム権限が共通付与されたCDB共通ユーザーは、CDB$ROOTで作成されたロックダウンプロファイルにのみ`PDB_LOCKDOWN`を設定できます。
アプリケーション共通の`SYSDBA`管理権限または`ALTER SYSTEM`システム権限を持つアプリケーション共通ユーザーは、アプリケーションルートで作成されたロックダウンプロファイルにのみ`PDB_LOCKDOWN`を設定できます。

## PDBロックダウンプロファイルの継承
PDBロックダウンプロファイルには、CDB$ROOT、アプリケーションルート、およびこれらに関連付けられているPDB間の継承動作があります。以下にプロファイルの継承についてまとめます。

- PDBに`PDB_LOCKDOWN`パラメータが設定されていない場合、PDBはCDB$ROOTまたはアプリケーションルートの`PDB_LOCKDOWN`パラメータの設定を継承します。
- アプリケーションルートに`PDB_LOCKDOWN`パラメータが設定されてない場合、アプリケーションルートはCDB$ROOTの`PDB_LOCKDOWN`パラメータの設定を継承します。
- PDBの`PDB_LOCKDOWN`パラメータ設定は、CDB$ROOTの設定より優先されます。同様に、アプリケーションPDBのロックダウンパラメータ設定はアプリケーションルートの設定より優先されます。
- PDBまたはアプリケーションPDBの`PDB_LOCKDOWN`パラメータがCDBロックダウンプロファイルに設定されている場合、PDBはCDB$ROOTまたはアプリケーションルートの`PDB_LOCKDOWN`によって設定されている**全てのロックダウンプロファイルを無視**します。
- アプリケーションPDBは、CDB$ROOTのものよりもアプリケーションルートのロックダウンプロファイルを優先して継承します。
- CDBロックダウンプロファイルとアプリケーションロックダウンプロファイルとでルールが競合した場合、**CDBロックダウンプロファイルのルールが優先**されます。

例えばCDB$ROOTで`PDB_LOCKDOWN`を設定すると、`PDB_LOCKDOWN`がコンテナレベルで設定されていない限り、全てのPDBおよびアプリケーションルートがこの設定を継承します。

# アプリケーションコンテナにおけるポリシーの管理
## アプリケーション共通監査ポリシー
CDB共通監査ポリシーと同様、アプリケーション共通監査ポリシーは、マルチテナント環境の全てのPDBに使用できます。アプリケーション共通監査ポリシーは、アプリケーション共通オブジェクトおよびアプリケーション共通ロールのほか、システムアクションオプションおよびシステム権限オプションに対しても作成できます。
このタイプのポリシーはアプリケーションルートコンテナでのみ作成できますが、アプリケーション共通ユーザーとCDB共通ユーザーとの両方で有効にできます。
オブジェクトを監査する場合は、対象のオブジェクトがアプリケーション共通オブジェクトであることを確認してください。

## アプリケーション共通統合監査ポリシーについて
アプリケーションコンテナの場合、以下の手順に従うことで、アプリケーションのメンテナンスに使用されるアプリケーションコンテナスクリプトから共通統合監査ポリシーを実行できます。

1. アプリケーションルートに共通統合監査ポリシーを作成し、このポリシーを`CONTAINER = ALL`に設定します。このポリシーを次のステップで説明するスクリプトに含めることもできます。
1. アプリケーションのメンテナンスに使用するスクリプトの`BEGIN`/`END`ブロック内に、監査するSQL文を含めます。スクリプトに統合監査ポリシーを含める場合は、`CREATE AUDIT POLICY`と`AUDIT POLICY`の両方の文を含めるようにします。

アプリケーションのメンテナンス操作をアプリケーションルートまたはアプリケーションPDBでローカルに監査するには、上記の手順に従ったうえで、アプリケーションPDBを`ALTER PLUGGABLE DATABASE APPLICATION SYNC`文により同期します。

## ファイングレイン監査ポリシー
ファイングレイン監査は、指定した条件のデータへのアクセスをトリガーとして監査証跡を出力します。ファイングレイン監査ポリシーには、次のような制限があります。

- ファイングレイン監査ポリシーは、拡張データリンクオブジェクトに対して作成できません。
- CDB$ROOTでファイングレイン監査ポリシーを作成する場合、ファイングレイン監査ポリシーは**共通に適用されません**。全てのPDBで共通オブジェクトのアクセスを監査するようにファイングレイン監査ポリシーを作成する場合は、各PDBで明示的にポリシーを作成する必要があります。
- アプリケーション共通ファイングレイン監査ポリシーは、アプリケーションルートに接続し、`BEGIN`/`END`ブロック内にいる場合のみ作成できます。
- アプリケーション共通ファイングレイン監査ポリシーにハンドラがある場合、このハンドラはアプリケーション共通ユーザーまたはCDB共通ユーザーによって所有されている必要があります。
- アプリケーション共通ファイングレイン監査ポリシーは、ローカルPDBオブジェクトに対して作成できません。

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

### UNDOモードの特徴について正しい記述はどれですか。

- A) それぞれのPDBに対して個別にUNDOモードを設定できる。
- B) 共有UNDOモードで`FLASHBACK PLUGGABLE DATABASE`を実行した場合、フラッシュバックデータベースではなく完全リカバリが行われる。
- C) 共有UNDOモードではPDBフラッシュバック・データベースを行うことはできない。
- D) 共有UNDOモードでPDBリストアポイントを作成できる。

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

解答: D

A: 誤りです。UNDOモードの設定はCDB単位です。PDBごとに設定することはできません。

B: 誤りです。この場合、行われるのはPoint-in-Timeリカバリですから、完全リカバリではなく不完全リカバリが行われることになります。

C: 誤りです。共有UNDOモードであっても、クリーンPDBリストアポイントを復帰地点に指定することでフラッシュバックデータベースを行うことができます。

D: **正解です。**共有UNDOモードでは、クリーンPDBリストアポイントの他に、通常のPDBリストアポイントおよび保証付きPDBリストアポイントを作成することもできます。

</div>

### コンテナ・データベースの接続および切断について正しい記述はどれですか。

- A) PDBをアプリケーション・コンテナに接続する場合、PDBに含まれるアプリケーションのバージョンがアプリケーション・ルート・コンテナに含まれるアプリケーションのバージョンよりも新しいケースでは、PDBのアプリケーションは自動的にダウングレードされる。
- B) PDBをアプリケーション・コンテナに接続する場合、PDBとアプリケーション・コンテナとの文字セットおよび各国語文字セットは、常に一致する必要がある。
- C) アプリケーション・コンテナをCDB$ROOTから切断する場合、アプリケーション・コンテナに接続されているアプリケーションPDBも同時に切断される。
- D) アプリケーションPDBをアプリケーション・コンテナから切断する場合、アプリケーション・コンテナのインスタンスは停止されている必要がある。

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

解答: B

A: 誤りです。PDBと接続先アプリケーションコンテナに共通して含まれるアプリケーションのバージョンは一致している必要があります。両者のバージョンが異なっている場合、PDBのアプリケーションが自動的にダウングレードされることはありません。

B: **正解です。**文字セットに関わらず、アプリケーションコンテナとアプリケーションPDBの文字セットは一致する必要があります。なお、CDBの文字セットがAL32UTF8の場合に、各PDBとCDBの文字セットが異なっているケースについては問題ありません。

C: 誤りです。アプリケーションコンテナを切断する前には、アプリケーションPDBやアプリケーションシードをあらかじめ切断しておく必要があります。

D: 誤りです。切断するPDBはクローズされている必要がありますが、アプリケーションコンテナのインスタンスが停止されている必要はありません。

</div>

### アプリケーション・コンテナにおける、セキュリティについて正しい記述はどれですか。

- A) PDBロックダウン・プロファイルを既存のプロファイルを元に作成する場合、既存プロファイルの変更は新規プロファイルに常に継承される。
- B) CDB$ROOTでPDBロックダウン・プロファイルを設定しても、各PDBに対して設定が継承されない。
- C) CDB$ROOTでファイングレイン監査ポリシーを作成しても、各PDBに対してポリシーが継承されない。
- D) アプリケーションへのパッチ適用操作プロセスにおいて、アプリケーション共通統合監査ポリシーを有効化した場合、破壊的な操作であるためパッチ適用が失敗する。

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

解答: C

A: 誤りです。`FROM`句を指定してプロファイルを作成した場合には既存プロファイルの変更が継承されません。なお、`INCLUDING`句を指定した場合には既存プロファイルの変更が新規プロファイルに継承されます。

B: 誤りです。上位コンテナでPDBロックダウンプロファイルを設定した場合、ロックダウンプロファイルが設定されていない全ての下位PDBに対して設定が継承されます。

C: **正解です。**ファイングレイン監査ポリシーは、監査対象の各PDBで明示的に作成する必要があります。

D: 誤りです。アプリケーション共通統合監査ポリシーの有効化は破壊的な操作ではありません。

</div>

# 参考
[19c Multitenant管理者ガイド](https://docs.oracle.com/cd/F19136_01/multi/index.html)
[19c セキュリティ・ガイド](https://docs.oracle.com/cd/F19136_01/dbseg/index.html)
[コーソルOracleスペシャリストがチェック！Oracle Database 12c R2新機能](https://www.oracle.com/jp/technical-resources/articles/database/cosol-db12cr2/cosol-4.html)[^1]

[^1]: 最新のマニュアルとは一部内容が異なります。