Oracle 12c から導入されたマルチテナント・アーキテクチャは、1つの Oracle インスタンス上で複数の独立したデータベース(PDB)を稼働させる仕組みです。サーバーリソースの効率活用・統合管理・クラウド移行の容易化を目的としており、Oracle 21c 以降ではすべてのデータベースがマルチテナント構成になりました。
マルチテナントの概念を理解することは、Oracle 12c 以降の管理・開発において必須の知識です。
この記事でわかること
- CDB(コンテナデータベース)と PDB(プラガブルデータベース)の仕組みと違い
- PDB のサービス名を使った直接接続と ALTER SESSION SET CONTAINER による切り替え
- CDB・PDB の状態確認(V$PDBS / V$CONTAINERS)
- PDB の作成・オープン・クローズ・プラグイン/アンプラグ手順
- CDB_* ビューと DBA_* ビューの違い
- 共通ユーザー(C##prefix)とローカルユーザーの使い分け
CDB と PDB の基本概念
マルチテナント構成では1つの CDB(Container Database)の中に複数の PDB(Pluggable Database)が共存します。
| コンポーネント | 説明 |
|---|---|
| CDB$ROOT | CDB のルートコンテナ。Oracle システム管理データを保持。SYS/SYSTEM ユーザーはここに存在する |
| PDB$SEED | 新規 PDB 作成時のテンプレートとなるシードコンテナ(読み取り専用) |
| PDB(ユーザー PDB) | アプリケーションが使用するデータベース。それぞれ独立したデータ辞書を持つ |
| 共通ユーザー | CDB$ROOT とすべての PDB に存在するユーザー。名前に C## プレフィックスが必要(例: C##DBA_USER) |
| ローカルユーザー | 特定の PDB にのみ存在するユーザー。通常の CREATE USER で作成 |
CDB・PDB の状態を確認する
マルチテナント構成かどうかを確認する
-- CDB(マルチテナント)かどうかを確認する
SELECT name, cdb, con_id FROM V$DATABASE;
-- cdb = YES → マルチテナント構成
-- cdb = NO → 非CDB(Oracle 12c 以前の従来型)
-- 現在接続しているコンテナを確認する
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') AS con_name,
SYS_CONTEXT('USERENV', 'CON_ID') AS con_id
FROM DUAL;
-- CDB$ROOT に接続中 → CON_NAME = CDB$ROOT
-- PDB に接続中 → CON_NAME = PDB 名
PDB の一覧と状態を確認する
-- CDB$ROOT から全 PDB の状態を確認する(DBA 権限が必要)
SELECT
con_id,
name,
open_mode, -- READ WRITE / READ ONLY / MOUNTED(クローズ状態)
restricted, -- YES = RESTRICTED SESSION で制限中
recovery_status -- ENABLED / DISABLED(リカバリ状態)
FROM V$PDBS
ORDER BY con_id;
-- V$CONTAINERS でより詳細な情報を確認する
SELECT
con_id,
name,
open_mode,
con_uid, -- コンテナの一意識別子
guid -- グローバル一意識別子(プラグイン/アンプラグで使用)
FROM V$CONTAINERS
ORDER BY con_id;
PDB への接続方法
PDB への接続方法は2種類あります。通常のアプリケーション接続はサービス名を使った直接接続、DBA がコンテナを切り替える場合は ALTER SESSION SET CONTAINER を使います。
サービス名を使って PDB に直接接続する(推奨)
-- tnsnames.ora の設定例(PDB_SALES という PDB に接続する) -- PDB_SALES = -- (DESCRIPTION = -- (ADDRESS = (PROTOCOL = TCP)(HOST = dbserver)(PORT = 1521)) -- (CONNECT_DATA = -- (SERVER = DEDICATED) -- (SERVICE_NAME = pdb_sales) -- PDB 名がデフォルトのサービス名になる -- ) -- ) -- SQL*Plus での接続例 -- sqlplus app_user/password@pdb_sales -- または -- sqlplus app_user/password@//dbserver:1521/pdb_sales -- PDB のサービス名を確認する(CDB$ROOT または各 PDB で実行) SELECT name, pdb, network_name FROM CDB_SERVICES WHERE con_id != 1 -- CDB$ROOT を除く ORDER BY pdb, name;
ALTER SESSION SET CONTAINER でコンテナを切り替える(DBA 操作)
-- CDB$ROOT に接続した DBA が特定の PDB に切り替える
-- SET CONTAINER 権限が必要(またはSYSDBA)
ALTER SESSION SET CONTAINER = PDB_SALES;
-- 現在のコンテナを確認する
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL;
-- CDB$ROOT に戻る
ALTER SESSION SET CONTAINER = CDB$ROOT;
PDB の起動・停止・作成
PDB を起動・停止する
-- CDB$ROOT から特定の PDB を起動する(READ WRITE モード) ALTER PLUGGABLE DATABASE pdb_sales OPEN; -- READ ONLY で起動する(レポート用途など) ALTER PLUGGABLE DATABASE pdb_sales OPEN READ ONLY; -- PDB を閉じる(MOUNTED 状態にする) ALTER PLUGGABLE DATABASE pdb_sales CLOSE IMMEDIATE; -- すべての PDB を起動する(CDB 再起動後によく実行する) ALTER PLUGGABLE DATABASE ALL OPEN; -- CDB 再起動時に自動的に PDB を OPEN にする設定 -- 各 PDB 内でオープン状態を保存する ALTER PLUGGABLE DATABASE pdb_sales SAVE STATE; -- 次回 CDB 再起動時に自動で OPEN される -- 保存状態を確認する SELECT con_name, state FROM DBA_PDB_SAVED_STATES;
新しい PDB を作成する
-- PDB$SEED からテンプレートを使って新規 PDB を作成する
-- CDB$ROOT に SYS/SYSDBA で接続して実行する
CREATE PLUGGABLE DATABASE pdb_new
ADMIN USER pdb_admin IDENTIFIED BY pdb_password -- PDB の管理者ユーザー
ROLES = (DBA)
FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/CDB/PDB$SEED/',
'/u01/app/oracle/oradata/CDB/PDB_NEW/')
-- FILE_NAME_CONVERT: シードのデータファイルパス → 新 PDB のデータファイルパス
PATH_PREFIX = '/u01/app/oracle/oradata/CDB/PDB_NEW/';
-- 作成後にオープンする
ALTER PLUGGABLE DATABASE pdb_new OPEN;
PDB のアンプラグとプラグイン
マルチテナントの強みはデータベースをアンプラグ(切り離し)→別の CDB にプラグインできる移植性です。ハードウェア移行・バージョンアップ・クラウド移行に活用できます。
PDB をアンプラグして別の CDB に移行する手順
-- ① 移行元 CDB で PDB をクローズしてアンプラグする
ALTER PLUGGABLE DATABASE pdb_sales CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE pdb_sales UNPLUG INTO '/tmp/pdb_sales.xml';
-- XML ファイル(マニフェスト)にメタデータが書き出される
-- ② アンプラグした PDB を移行元 CDB から削除する(KEEP DATAFILES = データファイルを保持)
DROP PLUGGABLE DATABASE pdb_sales KEEP DATAFILES;
-- ③ 移行先 CDB で PDB をプラグインする
CREATE PLUGGABLE DATABASE pdb_sales
USING '/tmp/pdb_sales.xml'
NOCOPY -- データファイルを移動しない(既存のパスを使う)
TEMPFILE REUSE;
-- ④ 互換性チェック(違反があれば事前に対処する)
SELECT * FROM PDB_PLUG_IN_VIOLATIONS WHERE name = 'PDB_SALES';
-- ⑤ プラグイン後に起動する
ALTER PLUGGABLE DATABASE pdb_sales OPEN;
CDB_* ビューと DBA_* ビューの違い
マルチテナント環境では CDB 全体を対象とした CDB_* ビューが追加されています。DBA_* ビューは現在接続しているコンテナの情報のみ返します。
CDB_* ビューで全 PDB のオブジェクトを横断確認する
-- CDB$ROOT から全 PDB のテーブルを確認する
SELECT con_id, owner, table_name, num_rows
FROM CDB_TABLES
WHERE owner NOT IN ('SYS', 'SYSTEM', 'OUTLN') -- システムユーザーを除く
ORDER BY con_id, owner, table_name;
-- 全 PDB のユーザーを確認する
SELECT con_id, username, account_status, common
FROM CDB_USERS
WHERE common = 'NO' -- ローカルユーザーのみ(YES = 共通ユーザー)
ORDER BY con_id, username;
-- 全 PDB のリソース使用状況(V$ ビューも CDB_ 版がある)
SELECT con_id, name, value
FROM V$PGASTAT
WHERE con_id != 0; -- CDB 全体を横断(con_id = 0 = 全コンテナ合計)
共通ユーザーとローカルユーザーの使い分け
共通ユーザーとローカルユーザーを作成する
-- 共通ユーザーの作成(CDB$ROOT で実行、名前に C## が必要)
-- CDB$ROOT とすべての PDB に同時に作成される
CREATE USER c##dba_monitor IDENTIFIED BY password CONTAINER=ALL;
GRANT CREATE SESSION TO c##dba_monitor CONTAINER=ALL;
GRANT SELECT ANY DICTIONARY TO c##dba_monitor CONTAINER=ALL;
-- ローカルユーザーの作成(特定の PDB に接続した状態で実行)
-- ALTER SESSION SET CONTAINER = pdb_sales; を実行してから
CREATE USER app_user IDENTIFIED BY password; -- CONTAINER=CURRENT がデフォルト
GRANT CREATE SESSION, CREATE TABLE TO app_user;
-- 共通ユーザーかどうかを確認する
SELECT username, common, con_id FROM CDB_USERS WHERE username IN ('C##DBA_MONITOR', 'APP_USER');
-- COMMON = YES → 共通ユーザー(CDB$ROOT で作成)
-- COMMON = NO → ローカルユーザー(PDB で作成)
共通ユーザーとローカルユーザーの使い分け
・共通ユーザー(C##prefix):CDB 全体を監視・管理する DBA・監査アカウント向け。全 PDB を横断操作できる
・ローカルユーザー:各 PDB のアプリケーションユーザー向け。他 PDB とは完全に独立している
・アプリケーション接続には通常ローカルユーザーを使い、C## ユーザーは管理・監査専用に限定することを推奨する
・共通ユーザー(C##prefix):CDB 全体を監視・管理する DBA・監査アカウント向け。全 PDB を横断操作できる
・ローカルユーザー:各 PDB のアプリケーションユーザー向け。他 PDB とは完全に独立している
・アプリケーション接続には通常ローカルユーザーを使い、C## ユーザーは管理・監査専用に限定することを推奨する
まとめ
- CDB$ROOTがマスターコンテナ。PDB$SEED はテンプレート。アプリは各 PDB に接続する
- サービス名直接接続が通常の接続方法。DBA は ALTER SESSION SET CONTAINER で切り替える
- V$PDBS / V$CONTAINERSで PDB の状態を確認する。SAVE STATE で再起動後の自動オープンを設定する
- CDB_* ビューはすべての PDB を横断確認できる。DBA_* ビューは現在のコンテナのみ
- 共通ユーザー(C##)は CDB 全体用。アプリは各 PDB のローカルユーザーで接続する
- アンプラグ/プラグインでデータベース単位の移行が可能。PDB_PLUG_IN_VIOLATIONS で互換性を事前確認する
マルチテナント環境での初期化パラメータ管理は 初期化パラメータ完全ガイドを参照してください。バックグラウンドプロセスとインスタンス構造は バックグラウンドプロセス完全ガイドも参照してください。