【Oracle】マルチテナント(CDB/PDB)完全ガイド|コンテナDB・プラガブルDB・接続・管理・CDB_* ビューまで解説

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## ユーザーは管理・監査専用に限定することを推奨する

まとめ

  • 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 で互換性を事前確認する

マルチテナント環境での初期化パラメータ管理は 初期化パラメータ完全ガイドを参照してください。バックグラウンドプロセスとインスタンス構造は バックグラウンドプロセス完全ガイドも参照してください。