Oracle DB

Oracle Database 総合ガイド — アーキテクチャ・機能・運用の全容

本ドキュメントは Oracle Database(以下 Oracle DB)の主要機能、内部アーキテクチャ、設定の具体例、および運用上の考慮事項を包括的にまとめたものである。Oracle Database 19c / 21c / 23ai を主な対象バージョンとし、SRE・DBA が日常業務で参照できる実用的なリファレンスを目指す。


目次

  1. Oracle Database の概要と歴史
  2. アーキテクチャ概要
  3. インスタンスアーキテクチャ — SGA と PGA
  4. プロセスアーキテクチャ
  5. ストレージアーキテクチャ
  6. マルチテナント・アーキテクチャ (CDB/PDB)
  7. SQL 処理とオプティマイザ
  8. トランザクション管理と同時実行制御
  9. REDO / UNDO と障害復旧
  10. バックアップとリカバリ (RMAN)
  11. Data Guard — 高可用性とディザスタリカバリ
  12. Oracle Real Application Clusters (RAC)
  13. Automatic Storage Management (ASM)
  14. パーティショニング
  15. インデックス戦略
  16. セキュリティ
  17. パフォーマンスチューニング
  18. 自動化機能 — AWR / ADDM / SQL Tuning Advisor
  19. Oracle Net とネットワーク構成
  20. GoldenGate 連携とレプリケーション
  21. Oracle Cloud Infrastructure (OCI) 連携
  22. 運用ベストプラクティス
  23. トラブルシューティング
  24. まとめ

1. Oracle Database の概要と歴史

1.1 Oracle Database とは

Oracle Database は、Oracle Corporation が開発・提供するマルチモデルのリレーショナルデータベース管理システム(RDBMS)である。1979 年に最初の商用バージョンがリリースされて以来、エンタープライズ市場でのシェアを拡大し続け、金融・通信・政府機関など、ミッションクリティカルなワークロードを支える基盤として広く採用されている。

1.2 バージョンの変遷

バージョンリリース年主な特徴
Oracle V21979商用 RDBMS 初リリース(V1 は社内のみ)
Oracle 71992PL/SQL ストアドプロシージャ、トリガー
Oracle 8i1999Java VM 統合、インターネット対応
Oracle 9i2001Real Application Clusters (RAC)
Oracle 10g2003Automatic Storage Management (ASM)、Grid Computing
Oracle 11g2007Active Data Guard、Real Application Testing
Oracle 12c2013マルチテナント・アーキテクチャ (CDB/PDB)
Oracle 18c / 19c2018-2019年次リリースモデル、19c は長期サポート版
Oracle 21c2021Blockchain テーブル、JSON ネイティブ型
Oracle 23ai2024AI Vector Search、JSON Relational Duality

1.3 エディション

エディション用途
Enterprise Edition (EE)大規模本番環境。RAC、パーティショニング等はオプションとして追加可能
Standard Edition 2 (SE2)中小規模。最大 2 ソケットまで
Express Edition (XE)無償版。CPU・メモリ・データサイズに制約あり
Personal Edition開発・テスト用の単一ユーザー版

1.4 ライセンスモデル

Oracle DB のライセンスは主に以下の 2 つの課金モデルで提供される:

  • Named User Plus (NUP): データベースにアクセスするユーザー数ベース(最小ユーザー数あり)
  • Processor License: サーバーの CPU コア数ベース(Core Factor テーブルによる係数あり)
-- Core Factor の例(Intel / AMD の場合)
--   Core Factor = 0.5
--   8 コアの場合: 8 × 0.5 = 4 Processor License が必要

2. アーキテクチャ概要

Oracle Database のアーキテクチャは大きく インスタンスデータベース の 2 つの層に分かれる。

2.1 インスタンスとデータベース

┌─────────────────────────────────────────────────┐
│                  Oracle Instance                 │
│  ┌──────────────────────────────────────────┐   │
│  │         System Global Area (SGA)          │   │
│  │  ┌──────────┐ ┌───────────┐ ┌─────────┐ │   │
│  │  │  Shared   │ │  Database │ │  Redo   │ │   │
│  │  │  Pool     │ │  Buffer   │ │  Log    │ │   │
│  │  │          │ │  Cache    │ │  Buffer │ │   │
│  │  └──────────┘ └───────────┘ └─────────┘ │   │
│  │  ┌──────────┐ ┌───────────┐ ┌─────────┐ │   │
│  │  │  Large   │ │  Java     │ │ Streams │ │   │
│  │  │  Pool    │ │  Pool     │ │  Pool   │ │   │
│  │  └──────────┘ └───────────┘ └─────────┘ │   │
│  └──────────────────────────────────────────┘   │
│                                                  │
│  ┌────────────────────────────────────┐         │
│  │   Background Processes             │         │
│  │   DBWn, LGWR, CKPT, SMON, PMON,  │         │
│  │   ARCH, RECO, MMON, MMNL ...     │         │
│  └────────────────────────────────────┘         │
│                                                  │
│  ┌────────────────────────────────────┐         │
│  │   Program Global Area (PGA)        │         │
│  │   (各サーバープロセスごとに確保)    │         │
│  └────────────────────────────────────┘         │
└─────────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────┐
│               Oracle Database (物理ファイル)       │
│  ┌──────────┐ ┌───────────┐ ┌────────────────┐ │
│  │ Data     │ │ Redo Log  │ │ Control Files  │ │
│  │ Files    │ │ Files     │ │                │ │
│  └──────────┘ └───────────┘ └────────────────┘ │
│  ┌──────────┐ ┌───────────┐ ┌────────────────┐ │
│  │ Archive  │ │ Temp      │ │ Parameter File │ │
│  │ Logs     │ │ Files     │ │ (SPFILE/PFILE) │ │
│  └──────────┘ └───────────┘ └────────────────┘ │
└─────────────────────────────────────────────────┘

インスタンス はメモリ構造(SGA + PGA)とバックグラウンドプロセス群の組み合わせであり、Oracle Database を起動すると OS 上にインスタンスが作成される。データベース はディスク上の物理ファイル群(データファイル、REDO ログファイル、制御ファイルなど)を指す。

RAC 環境では、1 つのデータベースに対して複数のインスタンスが同時にアクセスする。

2.2 論理ストレージ構造

Oracle DB の論理ストレージは以下の階層構造を持つ:

Tablespace
  └── Segment(テーブル、インデックスなど)
        └── Extent(連続したデータブロックの集合)
              └── Data Block(最小 I/O 単位、デフォルト 8KB)

2.3 初期化パラメータファイル

Oracle DB の起動時の動作は初期化パラメータで制御される。

-- SPFILE(サーバーパラメータファイル)の場所確認
SHOW PARAMETER spfile;

-- 主要パラメータの確認
SHOW PARAMETER db_name;
SHOW PARAMETER db_block_size;
SHOW PARAMETER sga_target;
SHOW PARAMETER pga_aggregate_target;
SHOW PARAMETER processes;
SHOW PARAMETER sessions;

SPFILE vs PFILE:

  • SPFILE (spfile<SID>.ora): バイナリ形式。ALTER SYSTEM で動的に変更可能。推奨。
  • PFILE (init<SID>.ora): テキスト形式。手動編集が必要。
-- SPFILE からパラメータを変更(即時 + 永続)
ALTER SYSTEM SET sga_target = 8G SCOPE=BOTH;

-- メモリのみ変更(再起動で元に戻る)
ALTER SYSTEM SET pga_aggregate_target = 4G SCOPE=MEMORY;

-- SPFILE のみ変更(次回起動時から有効)
ALTER SYSTEM SET db_files = 500 SCOPE=SPFILE;

3. インスタンスアーキテクチャ — SGA と PGA

3.1 System Global Area (SGA)

SGA はすべてのサーバープロセスとバックグラウンドプロセスが共有するメモリ領域である。Oracle 10g 以降は Automatic Shared Memory Management (ASMM) により、SGA_TARGET パラメータを設定すれば各コンポーネントのサイズを自動調整できる。

3.1.1 Database Buffer Cache

データファイルから読み込んだデータブロックをキャッシュするメモリ領域。物理 I/O を削減し、パフォーマンスを向上させる。

-- Buffer Cache のサイズ確認
SHOW PARAMETER db_cache_size;

-- Buffer Cache のヒット率を確認
SELECT 
    1 - (physical_reads / (db_block_gets + consistent_gets)) AS buffer_cache_hit_ratio
FROM (
    SELECT 
        SUM(CASE WHEN name = 'physical reads' THEN value END) AS physical_reads,
        SUM(CASE WHEN name = 'db block gets' THEN value END) AS db_block_gets,
        SUM(CASE WHEN name = 'consistent gets' THEN value END) AS consistent_gets
    FROM v$sysstat
    WHERE name IN ('physical reads', 'db block gets', 'consistent gets')
);

-- 目標: ヒット率 95% 以上(OLTP)

LRU(Least Recently Used)アルゴリズム によりバッファの入れ替えが行われる。Oracle は touch count 方式を採用しており、頻繁にアクセスされるブロックは hot end に、あまりアクセスされないブロックは cold end に配置される。

-- Buffer Pool の構成(KEEP / RECYCLE / DEFAULT)
ALTER SYSTEM SET db_keep_cache_size = 512M;
ALTER SYSTEM SET db_recycle_cache_size = 256M;

-- テーブルを KEEP プールに割り当て
ALTER TABLE hr.employees STORAGE (BUFFER_POOL KEEP);

3.1.2 Shared Pool

SQL 文のパース結果(実行計画)やデータディクショナリ情報をキャッシュする領域。

-- Shared Pool のサイズ確認
SHOW PARAMETER shared_pool_size;

-- Library Cache のヒット率
SELECT 
    namespace,
    gets,
    gethits,
    ROUND(gethitratio * 100, 2) AS hit_ratio_pct
FROM v$librarycache
WHERE namespace IN ('SQL AREA', 'TABLE/PROCEDURE', 'BODY', 'TRIGGER');

-- Shared Pool 内の SQL カーソル確認
SELECT sql_id, executions, buffer_gets, disk_reads, 
       ROUND(buffer_gets/NULLIF(executions,0)) AS gets_per_exec,
       sql_text
FROM v$sql
WHERE executions > 100
ORDER BY buffer_gets DESC
FETCH FIRST 20 ROWS ONLY;

バインド変数の重要性: リテラル値を直接 SQL に埋め込むと、SQL ごとに個別のカーソルが作成され Shared Pool を圧迫する(ハードパースの増加)。バインド変数を使用することで、同一の実行計画を再利用できる(ソフトパース)。

-- 悪い例(リテラル使用)
SELECT * FROM employees WHERE employee_id = 100;
SELECT * FROM employees WHERE employee_id = 101;
-- → それぞれ別の SQL としてパースされる

-- 良い例(バインド変数使用)
SELECT * FROM employees WHERE employee_id = :emp_id;
-- → 1 つの SQL カーソルを再利用

3.1.3 Redo Log Buffer

データ変更の REDO エントリを一時的に保持する循環バッファ。LGWR プロセスが定期的に REDO ログファイルに書き出す。

-- Redo Log Buffer のサイズ確認
SHOW PARAMETER log_buffer;

-- Redo Log Buffer の待機状況
SELECT name, value 
FROM v$sysstat 
WHERE name IN ('redo buffer allocation retries', 'redo log space requests');
-- retries が高い場合は log_buffer の増加を検討

3.1.4 Large Pool

RMAN バックアップ、共有サーバー接続のセッションメモリ、パラレルクエリのメッセージバッファに使用される。

SHOW PARAMETER large_pool_size;
ALTER SYSTEM SET large_pool_size = 256M SCOPE=BOTH;

3.1.5 Java Pool / Streams Pool

  • Java Pool: Oracle JVM のセッション固有の Java コードとデータ用
  • Streams Pool: Oracle Streams / GoldenGate のキャプチャ・適用プロセス用

3.2 Automatic Memory Management

Oracle 11g 以降、MEMORY_TARGET を設定すると SGA と PGA の両方を自動管理する Automatic Memory Management (AMM) が利用可能。

-- AMM の設定例
ALTER SYSTEM SET memory_target = 16G SCOPE=SPFILE;
ALTER SYSTEM SET memory_max_target = 20G SCOPE=SPFILE;

-- SGA と PGA の個別管理(ASMM)に切り替える場合
ALTER SYSTEM SET memory_target = 0 SCOPE=SPFILE;
ALTER SYSTEM SET sga_target = 10G SCOPE=SPFILE;
ALTER SYSTEM SET pga_aggregate_target = 4G SCOPE=SPFILE;

推奨: 大規模環境(SGA 数十 GB 以上)では AMM よりも ASMM(SGA_TARGET + PGA_AGGREGATE_TARGET)の方が制御しやすい。Huge Pages を使用する場合は AMM は利用できないため、ASMM を使用する。

3.3 Program Global Area (PGA)

PGA は各サーバープロセスに専用のメモリ領域であり、ソート領域、ハッシュ結合のワーク領域、セッション情報を保持する。

-- PGA の設定
SHOW PARAMETER pga_aggregate_target;
SHOW PARAMETER pga_aggregate_limit;

-- PGA の使用状況
SELECT 
    name, 
    ROUND(value/1024/1024, 2) AS mb
FROM v$pgastat
WHERE name IN (
    'aggregate PGA target parameter',
    'aggregate PGA auto target',
    'total PGA allocated',
    'total PGA used for auto workareas',
    'over allocation count'
);

-- セッション別 PGA 使用量
SELECT 
    s.sid, s.serial#, s.username,
    ROUND(p.pga_used_mem/1024/1024, 2) AS pga_used_mb,
    ROUND(p.pga_alloc_mem/1024/1024, 2) AS pga_alloc_mb,
    ROUND(p.pga_max_mem/1024/1024, 2) AS pga_max_mb
FROM v$session s JOIN v$process p ON s.paddr = p.addr
WHERE s.type = 'USER'
ORDER BY p.pga_alloc_mem DESC
FETCH FIRST 10 ROWS ONLY;

3.4 Huge Pages(Linux)

大規模な SGA を効率的に管理するために、Linux の Huge Pages(2MB / 1GB ページ)を使用することが強く推奨される。

# 現在の Huge Pages 設定確認
cat /proc/meminfo | grep -i huge

# 必要な Huge Pages 数の計算(SGA 16GB の場合)
# 16 * 1024 / 2 = 8192 ページ(2MB ページの場合)
# 余裕を持って +10%
echo 9012 > /proc/sys/vm/nr_hugepages

# 永続化(/etc/sysctl.conf)
vm.nr_hugepages = 9012

# Oracle の初期化パラメータ
ALTER SYSTEM SET use_large_pages = ONLY SCOPE=SPFILE;
-- ONLY: Huge Pages 確保できない場合は起動失敗(推奨)
-- TRUE: 可能なら使用(デフォルト)
-- FALSE: 使用しない

4. プロセスアーキテクチャ

Oracle DB のプロセスは、ユーザープロセスサーバープロセスバックグラウンドプロセス の 3 種類に大別される。

4.1 ユーザープロセスとサーバープロセス

  • ユーザープロセス: クライアントアプリケーション(SQL*Plus、JDBC ドライバ等)が起動するプロセス
  • サーバープロセス: ユーザーの要求を処理する Oracle のプロセス。SQL のパース・実行、データブロックの読み取り等を行う

接続モード:

モード説明用途
Dedicated Server1 ユーザー = 1 サーバープロセスOLTP(デフォルト)
Shared Server複数ユーザーがサーバープロセスを共有大量接続の Web アプリ
DRCP (Database Resident Connection Pooling)データベース側で接続プーリング多数の短時間接続
-- DRCP の設定
EXEC DBMS_CONNECTION_POOL.CONFIGURE_POOL(
    pool_name   => 'SYS_DEFAULT_CONNECTION_POOL',
    minsize     => 10,
    maxsize     => 100,
    incrsize    => 5,
    session_cached_cursors => 50,
    inactivity_timeout     => 300,
    max_think_time         => 600
);

-- DRCP の起動
EXEC DBMS_CONNECTION_POOL.START_POOL;

-- DRCP 接続文字列例
-- jdbc:oracle:thin:@//dbhost:1521/orcl:POOLED

4.2 主要バックグラウンドプロセス

4.2.1 DBWn (Database Writer)

変更されたデータブロック(dirty buffer)をデータファイルに書き込む。

-- DBW プロセス数の設定(CPU コア数に応じて)
SHOW PARAMETER db_writer_processes;
ALTER SYSTEM SET db_writer_processes = 4 SCOPE=SPFILE;
-- 一般に CPU コア数 / 8 程度(最大 36)

DBWn が書き込みを行うタイミング:

  • チェックポイント発生時
  • dirty buffer が閾値を超えた時
  • フリーバッファがなくなった時
  • タイムアウト(3 秒ごと)

4.2.2 LGWR (Log Writer)

Redo Log Buffer の内容を Online Redo Log ファイルに書き込む。以下のタイミングで書き込みが行われる:

  • COMMIT 発行時
  • Redo Log Buffer が 1/3 になった時
  • DBWn が dirty buffer を書き込む前
  • 3 秒ごと
-- Redo Log のグループ確認
SELECT group#, status, bytes/1024/1024 AS mb, members 
FROM v$log;

-- Redo Log ファイルの物理パス
SELECT group#, member FROM v$logfile ORDER BY group#;

重要: LGWR のパフォーマンスはトランザクションスループットに直結する。Redo Log ファイルは高速ストレージ(SSD 推奨)に配置すべきである。

4.2.3 CKPT (Checkpoint)

チェックポイント情報をデータファイルヘッダと制御ファイルに書き込む。チェックポイントは DBWn に dirty buffer の書き込みをトリガーする。

-- チェックポイント頻度に関するパラメータ
SHOW PARAMETER log_checkpoint_interval;
SHOW PARAMETER log_checkpoint_timeout;

-- 増分チェックポイント(FAST_START_MTTR_TARGET で制御)
SHOW PARAMETER fast_start_mttr_target;
-- 推奨: 30-60 秒(障害復旧時間の目標値)
ALTER SYSTEM SET fast_start_mttr_target = 60 SCOPE=BOTH;

4.2.4 SMON (System Monitor)

  • インスタンス復旧(クラッシュ後の自動ロールフォワード / ロールバック)
  • 不要な一時セグメントの回収
  • Dictionary Managed Tablespace の空き領域の結合

4.2.5 PMON (Process Monitor)

  • 異常終了したユーザープロセスの検出とクリーンアップ
  • ロックの解放
  • リスナーへのサービス情報の登録
-- PMON のリスナー登録設定
SHOW PARAMETER local_listener;
SHOW PARAMETER remote_listener;

ALTER SYSTEM SET local_listener = '(ADDRESS=(PROTOCOL=TCP)(HOST=dbhost)(PORT=1521))' SCOPE=BOTH;

4.2.6 ARCn (Archiver)

ARCHIVELOG モードで動作している場合、Online Redo Log のスイッチ時にログをアーカイブ先にコピーする。

-- ARCHIVELOG モードの確認
ARCHIVE LOG LIST;

-- ARCHIVELOG モードへの変更
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;

-- アーカイブ先の設定
ALTER SYSTEM SET log_archive_dest_1 = 'LOCATION=/u01/archive VALID_FOR=(ALL_LOGFILES,ALL_ROLES)' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_format = 'arch_%t_%s_%r.arc' SCOPE=SPFILE;

-- アーカイバープロセス数
ALTER SYSTEM SET log_archive_max_processes = 4 SCOPE=BOTH;

4.2.7 MMON / MMNL (Manageability Monitor)

  • MMON: AWR スナップショットの自動取得、ADDM 分析の実行
  • MMNL: ASH(Active Session History)データの SGA からディスクへのフラッシュ

4.2.8 RECO (Recoverer)

分散トランザクションの in-doubt トランザクションを解決する。

4.3 プロセス確認

-- バックグラウンドプロセス一覧
SELECT pname, pid, spid AS os_pid, program 
FROM v$process 
WHERE pname IS NOT NULL
ORDER BY pname;

-- サーバープロセスの確認(OS レベル)
-- Linux の場合
ps -ef | grep ora_ | grep -v grep

5. ストレージアーキテクチャ

5.1 テーブルスペース

テーブルスペースはセグメント(テーブル、インデックス等)を格納する論理コンテナであり、1 つ以上のデータファイルで構成される。

-- テーブルスペースの確認
SELECT tablespace_name, status, contents, extent_management, 
       segment_space_management, bigfile
FROM dba_tablespaces;

-- テーブルスペースの使用量
SELECT 
    ts.tablespace_name,
    ROUND(ts.total_mb, 2) AS total_mb,
    ROUND(ts.total_mb - NVL(fs.free_mb, 0), 2) AS used_mb,
    ROUND(NVL(fs.free_mb, 0), 2) AS free_mb,
    ROUND((ts.total_mb - NVL(fs.free_mb, 0)) / ts.total_mb * 100, 2) AS pct_used
FROM (
    SELECT tablespace_name, SUM(bytes)/1024/1024 AS total_mb 
    FROM dba_data_files GROUP BY tablespace_name
) ts
LEFT JOIN (
    SELECT tablespace_name, SUM(bytes)/1024/1024 AS free_mb 
    FROM dba_free_space GROUP BY tablespace_name
) fs ON ts.tablespace_name = fs.tablespace_name
ORDER BY pct_used DESC;

テーブルスペースの種類

種類説明
SYSTEMデータディクショナリを格納。必須テーブルスペース
SYSAUX自動ワークロードリポジトリ (AWR) 等の補助機能用
UNDOUNDO データを格納。自動 UNDO 管理で使用
TEMPソート、ハッシュ結合等の一時データ用
ユーザー定義アプリケーションデータ用
-- テーブルスペースの作成
CREATE TABLESPACE app_data
    DATAFILE '/u02/oradata/orcl/app_data01.dbf' SIZE 10G
    AUTOEXTEND ON NEXT 1G MAXSIZE 50G
    EXTENT MANAGEMENT LOCAL
    SEGMENT SPACE MANAGEMENT AUTO;

-- Bigfile テーブルスペース(巨大な単一データファイル、最大 128TB)
CREATE BIGFILE TABLESPACE app_bigdata
    DATAFILE '/u02/oradata/orcl/app_bigdata01.dbf' SIZE 100G
    AUTOEXTEND ON NEXT 10G MAXSIZE UNLIMITED;

-- UNDO テーブルスペースの作成
CREATE UNDO TABLESPACE undotbs2
    DATAFILE '/u02/oradata/orcl/undotbs02.dbf' SIZE 5G
    AUTOEXTEND ON NEXT 500M MAXSIZE 20G;

-- TEMP テーブルスペースの作成
CREATE TEMPORARY TABLESPACE temp2
    TEMPFILE '/u02/oradata/orcl/temp02.dbf' SIZE 5G
    AUTOEXTEND ON NEXT 500M MAXSIZE 20G;

5.2 データファイル

-- データファイル一覧
SELECT file_id, file_name, tablespace_name, 
       ROUND(bytes/1024/1024) AS size_mb,
       autoextensible, 
       ROUND(maxbytes/1024/1024) AS max_mb
FROM dba_data_files
ORDER BY tablespace_name, file_id;

-- データファイルの追加
ALTER TABLESPACE app_data 
    ADD DATAFILE '/u02/oradata/orcl/app_data02.dbf' SIZE 10G
    AUTOEXTEND ON NEXT 1G MAXSIZE 50G;

-- データファイルのリサイズ
ALTER DATABASE DATAFILE '/u02/oradata/orcl/app_data01.dbf' RESIZE 20G;

5.3 データブロック

Oracle DB の最小 I/O 単位。デフォルトは 8KB。ブロック構造は以下のようになっている:

┌──────────────────────────────┐
│       Block Header            │
│  (Common / Variable)          │
│  - Block Address (DBA)        │
│  - Block Type                 │
│  - Transaction Entries (ITL)  │
├──────────────────────────────┤
│       Table Directory         │
│       Row Directory           │
├──────────────────────────────┤
│       Free Space              │
├──────────────────────────────┤
│       Row Data                │
│  (下から上に向かって格納)      │
└──────────────────────────────┘
-- ブロックサイズの確認
SHOW PARAMETER db_block_size;

-- ブロック内のフリースペース管理パラメータ
-- PCTFREE: 更新用に予約する空き割合(デフォルト 10%)
-- PCTUSED: Locally Managed Tablespace + ASSM では非推奨

CREATE TABLE orders (
    order_id   NUMBER PRIMARY KEY,
    order_date DATE,
    status     VARCHAR2(20),
    details    VARCHAR2(4000)
) PCTFREE 20  -- 更新が頻繁な場合は値を上げる
  TABLESPACE app_data;

5.4 制御ファイル

データベースの物理構造を記録する重要なバイナリファイル。多重化が必須。

-- 制御ファイルの場所
SELECT name FROM v$controlfile;

-- 制御ファイルの多重化(SPFILE 変更後に再起動)
ALTER SYSTEM SET control_files = 
    '/u01/oradata/orcl/control01.ctl',
    '/u02/oradata/orcl/control02.ctl',
    '/u03/oradata/orcl/control03.ctl'
    SCOPE=SPFILE;

5.5 Online Redo Log

-- Redo Log グループの追加
ALTER DATABASE ADD LOGFILE GROUP 4 (
    '/u01/oradata/orcl/redo04a.log',
    '/u02/oradata/orcl/redo04b.log'
) SIZE 1G;

-- Redo Log のスイッチ頻度確認
SELECT 
    TO_CHAR(first_time, 'YYYY-MM-DD HH24') AS hour,
    COUNT(*) AS switches
FROM v$log_history
WHERE first_time > SYSDATE - 1
GROUP BY TO_CHAR(first_time, 'YYYY-MM-DD HH24')
ORDER BY 1;
-- 目標: 15-20 分に 1 回程度のスイッチ
-- 頻繁すぎる場合は Redo Log サイズを拡大

6. マルチテナント・アーキテクチャ (CDB/PDB)

Oracle 12c で導入されたマルチテナント・アーキテクチャは、1 つのコンテナ・データベース(CDB)内に複数のプラガブル・データベース(PDB)を収容する仕組みである。

6.1 アーキテクチャ概要

┌─────────────────────────────────────────────────┐
│           Container Database (CDB)               │
│                                                  │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐      │
│  │ CDB$ROOT │  │ PDB$SEED │  │  PDB1    │ ...  │
│  │          │  │(テンプレ │  │(ユーザー │      │
│  │(共通メタ │  │  ート)   │  │ データ)  │      │
│  │ データ)  │  │          │  │          │      │
│  └──────────┘  └──────────┘  └──────────┘      │
│                                                  │
│  共有: SGA, Background Processes, Redo Log,      │
│        UNDO Tablespace(デフォルト), Control Files │
│  分離: データファイル、TEMP TBS、一部の設定       │
└─────────────────────────────────────────────────┘

6.2 マルチテナントの利点

  • 統合密度の向上: 1 つのインスタンスで複数のデータベースを管理
  • リソースの効率的共有: SGA、バックグラウンドプロセスの共有
  • 運用の簡素化: パッチ適用やアップグレードを CDB レベルで一括管理
  • PDB の可搬性: Unplug/Plug 操作で PDB を別の CDB に移動可能

6.3 CDB / PDB の操作

-- CDB の確認
SELECT cdb FROM v$database;

-- PDB 一覧
SELECT pdb_id, pdb_name, status, con_id 
FROM cdb_pdbs 
ORDER BY pdb_id;

-- 現在のコンテナ確認
SHOW CON_NAME;
SHOW CON_ID;

-- PDB の作成
CREATE PLUGGABLE DATABASE pdb_sales
    ADMIN USER pdb_admin IDENTIFIED BY "SecurePass123!"
    STORAGE (MAXSIZE 50G MAX_SHARED_TEMP_SIZE 5G)
    DEFAULT TABLESPACE sales_data
        DATAFILE '/u02/oradata/cdb1/pdb_sales/sales_data01.dbf' SIZE 10G
    PATH_PREFIX = '/u02/oradata/cdb1/pdb_sales/'
    FILE_NAME_CONVERT = ('/u02/oradata/cdb1/pdbseed/', '/u02/oradata/cdb1/pdb_sales/');

-- PDB のオープン
ALTER PLUGGABLE DATABASE pdb_sales OPEN;

-- すべての PDB を自動オープン(再起動時)
ALTER PLUGGABLE DATABASE ALL OPEN;
-- 永続化
ALTER PLUGGABLE DATABASE ALL SAVE STATE;

-- PDB への接続
ALTER SESSION SET CONTAINER = pdb_sales;
-- または
-- sqlplus sys@dbhost:1521/pdb_sales AS SYSDBA

6.4 PDB の Unplug / Plug

-- PDB のクローズと Unplug
ALTER PLUGGABLE DATABASE pdb_sales CLOSE IMMEDIATE;
ALTER PLUGGABLE DATABASE pdb_sales UNPLUG INTO '/tmp/pdb_sales.xml';
DROP PLUGGABLE DATABASE pdb_sales KEEP DATAFILES;

-- 別の CDB に Plug
CREATE PLUGGABLE DATABASE pdb_sales USING '/tmp/pdb_sales.xml'
    FILE_NAME_CONVERT = (
        '/u02/oradata/cdb1/pdb_sales/', 
        '/u02/oradata/cdb2/pdb_sales/'
    );
ALTER PLUGGABLE DATABASE pdb_sales OPEN;

6.5 PDB のリソース管理

-- Resource Manager を使用した PDB のリソース制限
BEGIN
    DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();
    
    DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN(
        plan    => 'cdb_resource_plan',
        comment => 'CDB resource allocation plan'
    );
    
    DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE(
        plan                  => 'cdb_resource_plan',
        pluggable_database    => 'pdb_sales',
        shares                => 3,          -- CPU 共有比率
        utilization_limit     => 80,         -- 最大 CPU 使用率 (%)
        parallel_server_limit => 50          -- パラレル実行サーバー制限 (%)
    );
    
    DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE(
        plan                  => 'cdb_resource_plan',
        pluggable_database    => 'pdb_dev',
        shares                => 1,
        utilization_limit     => 30,
        parallel_server_limit => 20
    );
    
    DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA();
    DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
END;
/

ALTER SYSTEM SET resource_manager_plan = 'cdb_resource_plan' SCOPE=BOTH;

6.6 PDB レベルのパラメータ設定

-- PDB 固有のパラメータ設定
ALTER SESSION SET CONTAINER = pdb_sales;
ALTER SYSTEM SET open_cursors = 500 SCOPE=BOTH;
ALTER SYSTEM SET cursor_sharing = 'FORCE' SCOPE=BOTH;

-- PDB の SGA / PGA 制限(19c 以降)
ALTER SYSTEM SET sga_target = 4G SCOPE=BOTH;        -- この PDB の SGA 上限
ALTER SYSTEM SET pga_aggregate_limit = 2G SCOPE=BOTH;

-- PDB のメモリ保証割合
ALTER SYSTEM SET sga_min_size = 2G SCOPE=BOTH;

7. SQL 処理とオプティマイザ

7.1 SQL 処理の流れ

  SQL 文の発行
       │
       ▼
  ┌─────────┐     共有プール内を検索
  │  パース  │──── ハッシュ値 + テキスト比較
  │ (Parse)  │     ┌── ソフトパース(既存カーソル再利用)
  └─────────┘     └── ハードパース(新規に実行計画を生成)
       │                    │
       │               ┌────┴────┐
       │               │オプティ  │
       │               │マイザ    │
       │               └────┬────┘
       │                    │
       ▼                    ▼
  ┌─────────┐     実行計画の決定
  │  実行   │
  │(Execute)│
  └─────────┘
       │
       ▼
  ┌─────────┐
  │ フェッチ │     SELECT の場合のみ
  │ (Fetch) │
  └─────────┘

7.2 コストベース・オプティマイザ (CBO)

Oracle は コストベース・オプティマイザ (CBO) を使用して最適な実行計画を選択する。CBO は統計情報に基づいてコスト(推定 I/O・CPU・ネットワーク)を算出する。

-- オプティマイザモードの確認
SHOW PARAMETER optimizer_mode;
-- ALL_ROWS(デフォルト): 全体のスループット最適化
-- FIRST_ROWS_n: 最初の n 行を返す速度を最適化

-- 統計情報の収集
EXEC DBMS_STATS.GATHER_TABLE_STATS(
    ownname    => 'HR',
    tabname    => 'EMPLOYEES',
    estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
    method_opt => 'FOR ALL COLUMNS SIZE AUTO',
    cascade    => TRUE,        -- インデックス統計も同時に収集
    degree     => 4            -- パラレル度
);

-- スキーマ全体の統計収集
EXEC DBMS_STATS.GATHER_SCHEMA_STATS(
    ownname    => 'HR',
    estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
    degree     => DBMS_STATS.AUTO_DEGREE,
    cascade    => TRUE,
    options    => 'GATHER STALE'  -- 古い統計のみ再収集
);

-- 自動統計収集の確認(デフォルトでメンテナンスウィンドウで実行)
SELECT client_name, status 
FROM dba_autotask_client
WHERE client_name = 'auto optimizer stats collection';

7.3 実行計画の確認

-- EXPLAIN PLAN
EXPLAIN PLAN FOR
SELECT e.employee_id, e.last_name, d.department_name
FROM employees e JOIN departments d ON e.department_id = d.department_id
WHERE d.location_id = 1700;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'ALL'));

-- 実行済み SQL の実際の実行計画(V$SQL_PLAN)
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(
    sql_id  => '4q3z7r8k5g6h2',
    format  => 'ALLSTATS LAST'
));

-- AWR に保存された実行計画
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR(
    sql_id  => '4q3z7r8k5g6h2',
    format  => 'ALL'
));

7.4 ヒント

オプティマイザに実行計画を指示するためのコメント形式の指令。

-- フルテーブルスキャンを強制
SELECT /*+ FULL(e) */ employee_id, last_name 
FROM employees e 
WHERE department_id = 50;

-- インデックスの使用を強制
SELECT /*+ INDEX(e emp_dept_idx) */ employee_id, last_name 
FROM employees e 
WHERE department_id = 50;

-- 結合方式の指定
SELECT /*+ USE_NL(e d) */   -- Nested Loop Join
    e.employee_id, d.department_name
FROM employees e JOIN departments d ON e.department_id = d.department_id;

SELECT /*+ USE_HASH(e d) */ -- Hash Join
    e.employee_id, d.department_name
FROM employees e JOIN departments d ON e.department_id = d.department_id;

-- パラレル実行
SELECT /*+ PARALLEL(e, 4) */ COUNT(*) FROM employees e;

-- SQL Plan Baseline で計画を固定
DECLARE
    l_plans PLS_INTEGER;
BEGIN
    l_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
        sql_id => '4q3z7r8k5g6h2',
        plan_hash_value => 1234567890,
        fixed => 'YES'
    );
    DBMS_OUTPUT.PUT_LINE('Plans loaded: ' || l_plans);
END;
/

7.5 Adaptive Query Optimization(12c 以降)

-- Adaptive Plans: 実行時に結合方式を切り替え
SHOW PARAMETER optimizer_adaptive_plans;
-- TRUE (デフォルト)

-- Adaptive Statistics: 実行時の統計フィードバック
SHOW PARAMETER optimizer_adaptive_statistics;
-- FALSE (19c デフォルト)

-- SQL Plan Directives
SELECT directive_id, type, state, reason
FROM dba_sql_plan_directives
WHERE type = 'DYNAMIC_SAMPLING'
ORDER BY last_used DESC
FETCH FIRST 20 ROWS ONLY;

8. トランザクション管理と同時実行制御

8.1 Oracle のトランザクションモデル

Oracle は 読み取り一貫性(Read Consistency) を提供する。これは、問い合わせの開始時点のデータスナップショットを返す仕組みであり、MVCC(Multi-Version Concurrency Control)に基づいている。

  • 文レベルの読み取り一貫性: 1 つの SQL 文の実行中は、文の開始時点のデータが見える(デフォルト)
  • トランザクションレベルの読み取り一貫性: SERIALIZABLE 分離レベルで実現

8.2 分離レベル

分離レベルOracle でのサポート説明
READ UNCOMMITTEDOracle は Dirty Read を許可しない
READ COMMITTED✓(デフォルト)コミット済みデータのみ読む。文レベルの一貫性
REPEATABLE READ直接はサポートしないが SERIALIZABLE で代替可能
SERIALIZABLEトランザクション開始時点のスナップショット
-- トランザクション分離レベルの設定
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- セッション単位で設定
ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;

-- Read-Only トランザクション
SET TRANSACTION READ ONLY;

8.3 ロック機構

Oracle は行レベルロックを基本とし、読み取りは書き込みをブロックせず、書き込みは読み取りをブロックしない(リーダーはライターをブロックしない、ライターはリーダーをブロックしない)。

-- 明示的な行ロック
SELECT * FROM employees WHERE employee_id = 100 FOR UPDATE;
SELECT * FROM employees WHERE employee_id = 100 FOR UPDATE NOWAIT;
SELECT * FROM employees WHERE employee_id = 100 FOR UPDATE WAIT 5;
SELECT * FROM employees WHERE employee_id = 100 FOR UPDATE SKIP LOCKED;

-- テーブルレベルのロック
LOCK TABLE employees IN EXCLUSIVE MODE NOWAIT;

-- ロック情報の確認
SELECT 
    s.sid, s.serial#, s.username, s.program,
    l.type, l.lmode, l.request, l.block,
    o.object_name, o.object_type
FROM v$lock l
JOIN v$session s ON l.sid = s.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
WHERE l.type IN ('TX', 'TM')
ORDER BY l.block DESC, s.sid;

-- ブロッキング・セッションの確認
SELECT 
    blocking_session AS blocker_sid,
    sid AS waiter_sid,
    serial#,
    username,
    event,
    seconds_in_wait,
    sql_id
FROM v$session
WHERE blocking_session IS NOT NULL;

8.4 デッドロック

Oracle はデッドロックを自動検出し、一方のトランザクションに ORA-00060 エラーを返す。デッドロック発生時はアラートログにダンプが書き込まれる。

-- デッドロック情報の確認
-- アラートログ($ORACLE_BASE/diag/rdbms/<db>/<sid>/trace/alert_<sid>.log)
-- に "ORA-00060: deadlock detected" が記録される

-- デッドロック頻度の確認
SELECT 
    TO_CHAR(sample_time, 'YYYY-MM-DD HH24') AS hour,
    COUNT(*) AS deadlock_count
FROM v$active_session_history
WHERE event = 'enq: TX - row lock contention'
  AND sample_time > SYSDATE - 7
GROUP BY TO_CHAR(sample_time, 'YYYY-MM-DD HH24')
ORDER BY 1;

8.5 UNDO 管理

-- 自動 UNDO 管理の設定
SHOW PARAMETER undo_management;     -- AUTO(デフォルト)
SHOW PARAMETER undo_tablespace;
SHOW PARAMETER undo_retention;      -- 秒単位(デフォルト 900 秒)

-- UNDO 保持期間の変更
ALTER SYSTEM SET undo_retention = 3600 SCOPE=BOTH;  -- 1 時間

-- UNDO 保持の保証(Flashback Query に必要)
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;

-- UNDO の使用状況
SELECT 
    tablespace_name,
    status,
    SUM(bytes)/1024/1024 AS mb,
    COUNT(*) AS extents
FROM dba_undo_extents
GROUP BY tablespace_name, status
ORDER BY tablespace_name, status;
-- STATUS: ACTIVE(使用中), UNEXPIRED(保持期間内), EXPIRED(再利用可能)

9. REDO / UNDO と障害復旧

9.1 REDO と UNDO の役割

メカニズム目的データの方向
REDO変更を再適用(ロールフォワード)してデータを最新状態に復元過去 → 現在
UNDO変更を取り消し(ロールバック)して過去の状態に戻す現在 → 過去

9.2 障害の種類と復旧

9.2.1 インスタンス障害(クラッシュリカバリ)

電源断やプロセス異常終了でインスタンスが突然停止した場合、次回起動時に SMON が自動的にクラッシュリカバリを実行する。

クラッシュリカバリの流れ:
1. ロールフォワード: Online Redo Log の REDO データを適用
   → コミット済み + 未コミットの両方の変更をデータファイルに反映
2. データベースオープン(ユーザーアクセス可能に)
3. ロールバック: UNDO データを使って未コミットのトランザクションを取り消し
   → SMON がバックグラウンドで実行
-- クラッシュリカバリ時間の制御
ALTER SYSTEM SET fast_start_mttr_target = 30 SCOPE=BOTH;
-- 目標: 30 秒以内にリカバリ完了

-- 推定リカバリ時間の確認
SELECT recovery_estimated_ios, actual_redo_blks, 
       target_redo_blks, target_mttr, estimated_mttr
FROM v$instance_recovery;

9.2.2 メディア障害(メディアリカバリ)

データファイルやディスクの物理的な損傷。RMAN バックアップとアーカイブログを使用して復旧する。

9.3 Flashback 技術

Oracle は UNDO データや Flashback Log を使って様々なレベルでのポイント・イン・タイム・リカバリを提供する。

-- Flashback Query(過去のデータを参照)
SELECT * FROM employees AS OF TIMESTAMP 
    SYSTIMESTAMP - INTERVAL '1' HOUR
WHERE employee_id = 100;

-- Flashback Version Query(行の変更履歴)
SELECT versions_starttime, versions_endtime, versions_operation,
       employee_id, salary
FROM employees 
    VERSIONS BETWEEN TIMESTAMP 
        SYSTIMESTAMP - INTERVAL '2' HOUR AND SYSTIMESTAMP
WHERE employee_id = 100;

-- Flashback Transaction Query(トランザクション単位)
SELECT xid, operation, undo_sql
FROM flashback_transaction_query
WHERE table_name = 'EMPLOYEES'
  AND commit_timestamp > SYSTIMESTAMP - INTERVAL '1' HOUR;

-- Flashback Table(テーブルを過去の状態に戻す)
ALTER TABLE employees ENABLE ROW MOVEMENT;
FLASHBACK TABLE employees TO TIMESTAMP 
    SYSTIMESTAMP - INTERVAL '30' MINUTE;

-- Flashback Drop(ゴミ箱からテーブルを復元)
FLASHBACK TABLE employees TO BEFORE DROP;

-- ゴミ箱の確認
SELECT object_name, original_name, type, droptime 
FROM user_recyclebin;

-- Flashback Database(データベース全体を過去の状態に戻す)
-- 事前設定
ALTER SYSTEM SET db_flashback_retention_target = 1440 SCOPE=BOTH; -- 24 時間
ALTER DATABASE FLASHBACK ON;

-- 実行
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
FLASHBACK DATABASE TO TIMESTAMP 
    TO_TIMESTAMP('2025-03-15 10:00:00', 'YYYY-MM-DD HH24:MI:SS');
ALTER DATABASE OPEN RESETLOGS;

9.4 Guaranteed Restore Points

-- Guaranteed Restore Point の作成
CREATE RESTORE POINT before_upgrade GUARANTEE FLASHBACK DATABASE;

-- 復元
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
FLASHBACK DATABASE TO RESTORE POINT before_upgrade;
ALTER DATABASE OPEN RESETLOGS;

-- Restore Point の確認
SELECT name, scn, time, guarantee_flashback_database, storage_size
FROM v$restore_point;

-- 削除(Flashback Log の解放)
DROP RESTORE POINT before_upgrade;

10. バックアップとリカバリ (RMAN)

10.1 RMAN (Recovery Manager) 概要

RMAN は Oracle DB の公式バックアップ・リカバリツールであり、以下の特徴を持つ:

  • ブロックレベルのバックアップ: 未使用ブロックをスキップする効率的なバックアップ
  • 増分バックアップ: Level 0(フル)と Level 1(差分/累積)
  • バックアップの自動管理: 保持ポリシーに基づく自動削除
  • ブロックメディアリカバリ: 損傷したブロックのみを修復
  • 暗号化・圧縮: バックアップデータの保護と効率化

10.2 RMAN の基本設定

# RMAN への接続
rman target /
rman target sys/password@orcl catalog rcat_user/password@rcat

# RMAN 設定の確認
RMAN> SHOW ALL;
-- RMAN 設定例
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
CONFIGURE BACKUP OPTIMIZATION ON;
CONFIGURE DEFAULT DEVICE TYPE TO DISK;
CONFIGURE CONTROLFILE AUTOBACKUP ON;
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/u03/backup/%F';
CONFIGURE CHANNEL DEVICE TYPE DISK FORMAT '/u03/backup/%U';
CONFIGURE CHANNEL DEVICE TYPE DISK MAXPIECESIZE 10G;
CONFIGURE DEVICE TYPE DISK PARALLELISM 4;
CONFIGURE COMPRESSION ALGORITHM 'MEDIUM';  -- LOW / MEDIUM / HIGH / BASIC
CONFIGURE ENCRYPTION FOR DATABASE ON;
CONFIGURE ENCRYPTION ALGORITHM 'AES256';

10.3 バックアップの実行

-- Level 0 増分バックアップ(フルバックアップ相当)
RMAN> BACKUP INCREMENTAL LEVEL 0 
      DATABASE 
      PLUS ARCHIVELOG DELETE INPUT
      TAG 'WEEKLY_FULL';

-- Level 1 差分増分バックアップ
RMAN> BACKUP INCREMENTAL LEVEL 1 
      DATABASE 
      PLUS ARCHIVELOG DELETE INPUT
      TAG 'DAILY_INCR';

-- Level 1 累積増分バックアップ
RMAN> BACKUP INCREMENTAL LEVEL 1 CUMULATIVE 
      DATABASE 
      TAG 'DAILY_CUMUL';

-- 特定テーブルスペースのバックアップ
RMAN> BACKUP TABLESPACE app_data 
      TAG 'TS_APP_DATA';

-- 圧縮バックアップ
RMAN> BACKUP AS COMPRESSED BACKUPSET 
      INCREMENTAL LEVEL 0 DATABASE
      TAG 'COMPRESSED_FULL';

-- イメージコピー(データファイルの完全なコピー)
RMAN> BACKUP AS COPY DATABASE;

10.4 Block Change Tracking

増分バックアップの高速化のため、変更されたブロックを追跡するファイル。

-- Block Change Tracking の有効化
ALTER DATABASE ENABLE BLOCK CHANGE TRACKING 
    USING FILE '/u03/oradata/orcl/bct.ctf';

-- 確認
SELECT filename, status, bytes/1024/1024 AS mb
FROM v$block_change_tracking;

10.5 リカバリ操作

-- データベース全体のリカバリ
RMAN> STARTUP MOUNT;
RMAN> RESTORE DATABASE;
RMAN> RECOVER DATABASE;
RMAN> ALTER DATABASE OPEN;

-- ポイント・イン・タイム・リカバリ
RMAN> STARTUP MOUNT;
RMAN> RUN {
          SET UNTIL TIME "TO_DATE('2025-03-15 14:00:00','YYYY-MM-DD HH24:MI:SS')";
          RESTORE DATABASE;
          RECOVER DATABASE;
      }
RMAN> ALTER DATABASE OPEN RESETLOGS;

-- テーブルスペースのリカバリ
RMAN> SQL "ALTER TABLESPACE app_data OFFLINE IMMEDIATE";
RMAN> RESTORE TABLESPACE app_data;
RMAN> RECOVER TABLESPACE app_data;
RMAN> SQL "ALTER TABLESPACE app_data ONLINE";

-- ブロックメディアリカバリ(損傷ブロックのみ修復)
RMAN> BLOCKRECOVER DATAFILE 5 BLOCK 100, 200, 300;

-- テーブルのリカバリ(12c 以降)
RMAN> RECOVER TABLE hr.employees
      UNTIL TIME "TO_DATE('2025-03-15 14:00:00','YYYY-MM-DD HH24:MI:SS')"
      AUXILIARY DESTINATION '/u03/aux'
      REMAP TABLE hr.employees:employees_recovered;

10.6 バックアップの検証と管理

-- バックアップの検証(実際のリストアはしない)
RMAN> VALIDATE DATABASE;
RMAN> VALIDATE BACKUPSET 123;

-- バックアップリストの確認
RMAN> LIST BACKUP SUMMARY;
RMAN> LIST BACKUP OF DATABASE;
RMAN> LIST ARCHIVELOG ALL;

-- 不要バックアップのクロスチェックと削除
RMAN> CROSSCHECK BACKUP;
RMAN> CROSSCHECK ARCHIVELOG ALL;
RMAN> DELETE NOPROMPT OBSOLETE;
RMAN> DELETE NOPROMPT EXPIRED BACKUP;

-- リカバビリティのレポート
RMAN> REPORT NEED BACKUP;
RMAN> REPORT UNRECOVERABLE;

10.7 本番バックアップスクリプト例

#!/bin/bash
# daily_backup.sh - RMAN 日次バックアップスクリプト

export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1
export ORACLE_SID=orcl
export PATH=$ORACLE_HOME/bin:$PATH

LOG_DIR=/u03/backup/logs
DATE=$(date +%Y%m%d_%H%M%S)

rman target / log=${LOG_DIR}/rman_daily_${DATE}.log <<EOF
RUN {
    ALLOCATE CHANNEL c1 DEVICE TYPE DISK;
    ALLOCATE CHANNEL c2 DEVICE TYPE DISK;
    ALLOCATE CHANNEL c3 DEVICE TYPE DISK;
    ALLOCATE CHANNEL c4 DEVICE TYPE DISK;
    
    BACKUP AS COMPRESSED BACKUPSET
        INCREMENTAL LEVEL 1
        DATABASE
        FORMAT '/u03/backup/db_%d_%T_%U'
        TAG 'DAILY_INCR';
    
    BACKUP ARCHIVELOG ALL
        FORMAT '/u03/backup/arch_%d_%T_%U'
        TAG 'DAILY_ARCH'
        DELETE INPUT;
    
    DELETE NOPROMPT OBSOLETE;
    
    RELEASE CHANNEL c1;
    RELEASE CHANNEL c2;
    RELEASE CHANNEL c3;
    RELEASE CHANNEL c4;
}
EXIT;
EOF

# バックアップ結果の確認
if [ $? -eq 0 ]; then
    echo "Backup completed successfully" | mail -s "RMAN Backup OK - ${ORACLE_SID}" dba@example.com
else
    echo "Backup FAILED!" | mail -s "RMAN Backup FAILED - ${ORACLE_SID}" dba@example.com
fi

11. Data Guard — 高可用性とディザスタリカバリ

11.1 Data Guard 概要

Oracle Data Guard は、プライマリ・データベースの REDO データをスタンバイ・データベースに転送・適用することで、高可用性とディザスタリカバリを実現する機能である。

┌──────────────┐     REDO 転送      ┌──────────────┐
│   Primary    │ ──────────────────► │   Standby    │
│   Database   │     (LGWR/ARCH)     │   Database   │
│              │                     │              │
│  読み書き可   │                     │  Physical:   │
│              │                     │   REDO 適用   │
│              │                     │  Logical:    │
│              │                     │   SQL 適用    │
└──────────────┘                     └──────────────┘

11.2 スタンバイの種類

種類説明用途
Physical Standbyブロック単位の REDO 適用。プライマリと物理的に同一DR、読み取りオフロード(Active Data Guard)
Logical StandbyREDO を SQL に変換して適用。テーブル追加等が可能レポーティング、段階的移行
Snapshot StandbyPhysical Standby を一時的に読み書き可能にするテスト・検証

11.3 保護モード

モードデータ損失パフォーマンス影響設定
Maximum Protectionゼロ高い(SYNC 必須)スタンバイ障害時にプライマリも停止
Maximum Availabilityゼロ(通常時)中程度スタンバイ障害時は非同期に切り替え
Maximum Performanceわずかな損失あり低い(デフォルト)ASYNC 転送

11.4 Data Guard 構築例

-- === プライマリ側の設定 ===

-- Force Logging を有効化
ALTER DATABASE FORCE LOGGING;

-- スタンバイ REDO ログの追加(プライマリにも追加しておく)
ALTER DATABASE ADD STANDBY LOGFILE 
    GROUP 11 ('/u01/oradata/orcl/srl_g11.log') SIZE 1G;
ALTER DATABASE ADD STANDBY LOGFILE 
    GROUP 12 ('/u01/oradata/orcl/srl_g12.log') SIZE 1G;
ALTER DATABASE ADD STANDBY LOGFILE 
    GROUP 13 ('/u01/oradata/orcl/srl_g13.log') SIZE 1G;
ALTER DATABASE ADD STANDBY LOGFILE 
    GROUP 14 ('/u01/oradata/orcl/srl_g14.log') SIZE 1G;

-- 初期化パラメータ(プライマリ)
ALTER SYSTEM SET log_archive_config = 'DG_CONFIG=(orcl,orcl_stby)' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_dest_1 = 
    'LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orcl' SCOPE=BOTH;
ALTER SYSTEM SET log_archive_dest_2 = 
    'SERVICE=orcl_stby LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl_stby' SCOPE=BOTH;
ALTER SYSTEM SET fal_server = 'orcl_stby' SCOPE=BOTH;
ALTER SYSTEM SET fal_client = 'orcl' SCOPE=BOTH;
ALTER SYSTEM SET standby_file_management = 'AUTO' SCOPE=BOTH;
ALTER SYSTEM SET db_file_name_convert = 
    '/u02/oradata/orcl_stby/','/u02/oradata/orcl/' SCOPE=SPFILE;
ALTER SYSTEM SET log_file_name_convert = 
    '/u01/oradata/orcl_stby/','/u01/oradata/orcl/' SCOPE=SPFILE;
# RMAN でスタンバイデータベースを複製
rman target sys/password@orcl auxiliary sys/password@orcl_stby <<EOF
DUPLICATE TARGET DATABASE FOR STANDBY
    FROM ACTIVE DATABASE
    DORECOVER
    SPFILE
        SET db_unique_name='orcl_stby'
        SET log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orcl_stby'
        SET log_archive_dest_2='SERVICE=orcl LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl'
        SET fal_server='orcl'
        SET fal_client='orcl_stby'
    NOFILENAMECHECK;
EOF

11.5 スイッチオーバーとフェイルオーバー

-- === スイッチオーバー(計画的な切り替え) ===

-- プライマリ側: ロール切り替え
ALTER DATABASE COMMIT TO SWITCHOVER TO STANDBY WITH SESSION SHUTDOWN;
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE OPEN;

-- スタンバイ側: プライマリへ昇格
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
SHUTDOWN IMMEDIATE;
STARTUP;

-- === フェイルオーバー(緊急時の切り替え) ===

-- スタンバイ側で実行
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
ALTER DATABASE ACTIVATE STANDBY DATABASE;
ALTER DATABASE OPEN;

11.6 Active Data Guard

Physical Standby を読み取り専用でオープンしながら REDO 適用を継続する。レポーティングや読み取りクエリのオフロードに使用。

-- スタンバイ側
ALTER DATABASE OPEN READ ONLY;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;

-- Real-Time Query(オプション機能)
-- スタンバイが最新の REDO を適用しながらリアルタイムで参照可能

11.7 Data Guard Broker

# DG Broker の設定
dgmgrl sys/password@orcl

DGMGRL> CREATE CONFIGURATION dg_config AS
           PRIMARY DATABASE IS orcl
           CONNECT IDENTIFIER IS orcl;

DGMGRL> ADD DATABASE orcl_stby AS
           CONNECT IDENTIFIER IS orcl_stby
           MAINTAINED AS PHYSICAL;

DGMGRL> ENABLE CONFIGURATION;

# 状態確認
DGMGRL> SHOW CONFIGURATION;
DGMGRL> SHOW DATABASE orcl;
DGMGRL> SHOW DATABASE orcl_stby;

# Broker 経由のスイッチオーバー
DGMGRL> SWITCHOVER TO orcl_stby;

# Broker 経由のフェイルオーバー
DGMGRL> FAILOVER TO orcl_stby;

# Fast-Start Failover(自動フェイルオーバー)
DGMGRL> ENABLE FAST_START FAILOVER;

12. Oracle Real Application Clusters (RAC)

12.1 RAC 概要

Oracle RAC は、複数のサーバー(ノード)が 1 つの共有データベースに同時にアクセスする構成であり、高可用性とスケーラビリティを提供する。

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Node 1     │     │   Node 2     │     │   Node 3     │
│  Instance 1  │     │  Instance 2  │     │  Instance 3  │
│  SGA + PGA   │     │  SGA + PGA   │     │  SGA + PGA   │
└──────┬───────┘     └──────┬───────┘     └──────┬───────┘
       │    Private         │    Private         │
       │  Interconnect      │  Interconnect      │
       │  (Cache Fusion)    │  (Cache Fusion)    │
       ├────────────────────┼────────────────────┤
       │                    │                    │
       ▼                    ▼                    ▼
┌─────────────────────────────────────────────────────┐
│              Shared Storage (ASM / SAN)              │
│   Data Files │ Redo Logs │ Control Files │ Voting    │
└─────────────────────────────────────────────────────┘

12.2 Cache Fusion

RAC の中核技術。ノード間でメモリ上のデータブロックを高速転送する仕組み。

  • GCS (Global Cache Service): ブロックレベルのキャッシュ一貫性を維持
  • GES (Global Enqueue Service): ノード間のロック管理
  • GRD (Global Resource Directory): リソースのマスタリング情報
-- Cache Fusion の統計
SELECT inst_id, name, value 
FROM gv$sysstat
WHERE name LIKE 'gc%' 
  AND value > 0
ORDER BY inst_id, name;

-- Global Cache 転送の待機イベント
SELECT inst_id, event, total_waits, time_waited_micro/1000000 AS time_sec
FROM gv$system_event
WHERE event LIKE 'gc%'
  AND total_waits > 0
ORDER BY time_waited_micro DESC
FETCH FIRST 20 ROWS ONLY;

12.3 Oracle Clusterware

RAC の基盤となるクラスタウェア。以下のコンポーネントで構成:

  • Voting Disk: ノードのメンバーシップ管理(スプリットブレイン防止)
  • OCR (Oracle Cluster Registry): クラスタ構成情報
  • CSS (Cluster Synchronization Services): ノード間の同期
  • CRS (Cluster Ready Services): リソースの起動・監視・フェイルオーバー
# クラスタの状態確認
crsctl stat res -t

# ノード状態
olsnodes -s

# Voting Disk の確認
crsctl query css votedisk

# OCR の確認
ocrcheck

# サービスの管理
srvctl status database -d orcl
srvctl status instance -d orcl -i orcl1
srvctl start instance -d orcl -i orcl2
srvctl stop instance -d orcl -i orcl2 -o immediate
srvctl relocate service -d orcl -s app_service -oldinst orcl1 -newinst orcl2

12.4 RAC サービスと接続管理

-- サービスの作成
BEGIN
    DBMS_SERVICE.CREATE_SERVICE(
        service_name     => 'app_oltp',
        network_name     => 'app_oltp.example.com',
        aq_ha_notifications => TRUE,
        failover_method  => 'BASIC',
        failover_type    => 'SELECT',
        failover_retries => 30,
        failover_delay   => 5,
        clb_goal         => DBMS_SERVICE.CLB_GOAL_SHORT,
        goal             => DBMS_SERVICE.GOAL_SERVICE_TIME
    );
END;
/
# srvctl でサービスを管理
srvctl add service -d orcl -s app_oltp \
    -preferred orcl1,orcl2 \
    -available orcl3 \
    -failovermethod BASIC \
    -failovertype SELECT \
    -clbgoal SHORT \
    -rlbgoal SERVICE_TIME

srvctl start service -d orcl -s app_oltp

12.5 接続文字列例

-- 基本的な RAC 接続文字列(tnsnames.ora)
ORCL_RAC =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (LOAD_BALANCE = ON)
      (FAILOVER = ON)
      (ADDRESS = (PROTOCOL = TCP)(HOST = rac-node1-vip)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = rac-node2-vip)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = rac-node3-vip)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = app_oltp)
    )
  )

-- SCAN (Single Client Access Name) を使用(推奨)
ORCL_SCAN =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = orcl-scan)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = app_oltp)
    )
  )

-- Application Continuity 対応
ORCL_AC =
  (DESCRIPTION =
    (CONNECT_TIMEOUT = 5)(TRANSPORT_CONNECT_TIMEOUT = 3)(RETRY_COUNT = 3)
    (ADDRESS = (PROTOCOL = TCP)(HOST = orcl-scan)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = app_oltp)
    )
  )

12.6 RAC One Node

通常は 1 ノードで稼働し、障害時やメンテナンス時に別ノードにオンラインで移行する構成。コスト効率の高い HA ソリューション。

srvctl add database -d orcl -o $ORACLE_HOME -p +DATA/orcl/spfileorcl.ora -a DATA,FRA
srvctl add instance -d orcl -i orcl1 -n rac-node1
srvctl modify database -d orcl -e ONE  # RAC One Node モード

# オンライン移行
srvctl relocate database -d orcl -n rac-node2

13. Automatic Storage Management (ASM)

13.1 ASM 概要

ASM は Oracle が提供するボリュームマネージャ兼ファイルシステムで、Oracle DB のストレージ管理を自動化する。ディスクのストライピングとミラーリングを透過的に管理する。

┌─────────────────────────────────────────┐
│          ASM Instance                    │
│  (独自の SGA + バックグラウンドプロセス)  │
├─────────────────────────────────────────┤
│          Disk Groups                     │
│  ┌─────────────┐  ┌─────────────┐      │
│  │  +DATA       │  │  +FRA        │      │
│  │  Normal      │  │  External    │      │
│  │  Redundancy  │  │  Redundancy  │      │
│  │              │  │              │      │
│  │ ┌───┐ ┌───┐ │  │ ┌───┐ ┌───┐ │      │
│  │ │D1 │ │D2 │ │  │ │D5 │ │D6 │ │      │
│  │ └───┘ └───┘ │  │ └───┘ └───┘ │      │
│  │ ┌───┐ ┌───┐ │  │              │      │
│  │ │D3 │ │D4 │ │  │              │      │
│  │ └───┘ └───┘ │  │              │      │
│  └─────────────┘  └─────────────┘      │
└─────────────────────────────────────────┘

13.2 冗長性レベル

レベル説明必要ディスク数
ExternalASM はミラーリングしない(外部 RAID に依存)1+
Normal2-way ミラー(障害グループ間)2+
High3-way ミラー3+
Flexファイルごとにミラーレベルを指定可能3+

13.3 ASM ディスクグループの管理

-- ASM インスタンスに接続
-- sqlplus / as sysasm

-- ディスクグループの作成
CREATE DISKGROUP DATA
    NORMAL REDUNDANCY
    FAILGROUP fg1 DISK '/dev/oracleasm/disk1', '/dev/oracleasm/disk2'
    FAILGROUP fg2 DISK '/dev/oracleasm/disk3', '/dev/oracleasm/disk4'
    ATTRIBUTE 
        'compatible.asm'  = '19.0',
        'compatible.rdbms' = '19.0',
        'au_size' = '4M';    -- Allocation Unit サイズ

CREATE DISKGROUP FRA
    EXTERNAL REDUNDANCY
    DISK '/dev/oracleasm/disk5', '/dev/oracleasm/disk6'
    ATTRIBUTE 
        'compatible.asm'  = '19.0',
        'compatible.rdbms' = '19.0';

-- ディスクの追加
ALTER DISKGROUP DATA ADD DISK '/dev/oracleasm/disk7' FAILGROUP fg1;

-- ディスクの削除(リバランス実行)
ALTER DISKGROUP DATA DROP DISK disk1;

-- ディスクグループの状態確認
SELECT group_number, name, type, state, total_mb, free_mb, 
       ROUND((total_mb - free_mb)/total_mb * 100, 2) AS pct_used
FROM v$asm_diskgroup;

-- ディスクの状態確認
SELECT group_number, disk_number, name, path, total_mb, free_mb, 
       state, redundancy, failgroup
FROM v$asm_disk
WHERE group_number > 0
ORDER BY group_number, disk_number;

-- リバランスの進行状況
SELECT group_number, operation, state, power, est_minutes
FROM v$asm_operation;

-- リバランス速度の制御
ALTER DISKGROUP DATA REBALANCE POWER 8;  -- 1-1024(デフォルト 1)

13.4 ASM ファイルの管理

-- ASM 内のファイル一覧
SELECT name, type, bytes/1024/1024 AS mb, redundancy
FROM v$asm_file
WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name = 'DATA');

-- asmcmd ユーティリティ
-- $ asmcmd
-- ASMCMD> ls +DATA/orcl/
-- ASMCMD> du +DATA/orcl/
-- ASMCMD> cp +DATA/orcl/datafile/system.dbf /tmp/system.dbf

13.5 ASM と DB インスタンスの関係

# ASM を使用するデータベースの初期化パラメータ
# db_create_file_dest = '+DATA'
# db_recovery_file_dest = '+FRA'
# db_recovery_file_dest_size = 100G

# ASM インスタンスの管理
srvctl status asm
srvctl start asm
srvctl stop asm -o immediate

14. パーティショニング

14.1 パーティショニング概要

大規模テーブルやインデックスを小さな管理可能な部分(パーティション)に分割する。パーティション・プルーニング(不要なパーティションの自動除外)により、クエリ性能が大幅に向上する。

14.2 パーティション・タイプ

-- Range パーティション(最も一般的)
CREATE TABLE sales (
    sale_id     NUMBER,
    sale_date   DATE,
    amount      NUMBER(10,2),
    customer_id NUMBER
)
PARTITION BY RANGE (sale_date) (
    PARTITION p_2024_q1 VALUES LESS THAN (DATE '2024-04-01') TABLESPACE ts_2024q1,
    PARTITION p_2024_q2 VALUES LESS THAN (DATE '2024-07-01') TABLESPACE ts_2024q2,
    PARTITION p_2024_q3 VALUES LESS THAN (DATE '2024-10-01') TABLESPACE ts_2024q3,
    PARTITION p_2024_q4 VALUES LESS THAN (DATE '2025-01-01') TABLESPACE ts_2024q4,
    PARTITION p_2025_q1 VALUES LESS THAN (DATE '2025-04-01') TABLESPACE ts_2025q1,
    PARTITION p_max     VALUES LESS THAN (MAXVALUE)          TABLESPACE ts_default
);

-- Interval パーティション(自動作成)
CREATE TABLE transactions (
    txn_id    NUMBER,
    txn_date  DATE,
    amount    NUMBER(10,2)
)
PARTITION BY RANGE (txn_date)
INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
(PARTITION p_init VALUES LESS THAN (DATE '2024-01-01'));

-- List パーティション
CREATE TABLE customers (
    customer_id NUMBER,
    region      VARCHAR2(20),
    name        VARCHAR2(100)
)
PARTITION BY LIST (region) (
    PARTITION p_east  VALUES ('EAST', 'NORTHEAST'),
    PARTITION p_west  VALUES ('WEST', 'NORTHWEST'),
    PARTITION p_south VALUES ('SOUTH', 'SOUTHEAST'),
    PARTITION p_other VALUES (DEFAULT)
);

-- Hash パーティション
CREATE TABLE orders (
    order_id    NUMBER,
    customer_id NUMBER,
    order_date  DATE
)
PARTITION BY HASH (customer_id) PARTITIONS 16
STORE IN (ts1, ts2, ts3, ts4);

-- Composite パーティション(Range-Hash, Range-List 等)
CREATE TABLE order_items (
    order_id   NUMBER,
    item_id    NUMBER,
    order_date DATE,
    warehouse  VARCHAR2(20)
)
PARTITION BY RANGE (order_date)
SUBPARTITION BY LIST (warehouse)
(
    PARTITION p_2024 VALUES LESS THAN (DATE '2025-01-01') (
        SUBPARTITION p_2024_wh_east VALUES ('EAST'),
        SUBPARTITION p_2024_wh_west VALUES ('WEST'),
        SUBPARTITION p_2024_wh_default VALUES (DEFAULT)
    ),
    PARTITION p_2025 VALUES LESS THAN (DATE '2026-01-01') (
        SUBPARTITION p_2025_wh_east VALUES ('EAST'),
        SUBPARTITION p_2025_wh_west VALUES ('WEST'),
        SUBPARTITION p_2025_wh_default VALUES (DEFAULT)
    )
);

14.3 パーティション管理操作

-- パーティションの追加
ALTER TABLE sales ADD PARTITION p_2025_q2 
    VALUES LESS THAN (DATE '2025-07-01') TABLESPACE ts_2025q2;

-- パーティションの削除(データも削除)
ALTER TABLE sales DROP PARTITION p_2024_q1 UPDATE GLOBAL INDEXES;

-- パーティションの切り捨て(データのみ削除、構造は維持)
ALTER TABLE sales TRUNCATE PARTITION p_2024_q1 UPDATE GLOBAL INDEXES;

-- パーティションの分割
ALTER TABLE sales SPLIT PARTITION p_max AT (DATE '2025-07-01')
    INTO (PARTITION p_2025_q3, PARTITION p_max)
    UPDATE GLOBAL INDEXES;

-- パーティションの交換(ETL で頻用)
CREATE TABLE sales_staging AS SELECT * FROM sales WHERE 1=0;
-- staging テーブルにデータをロード後:
ALTER TABLE sales EXCHANGE PARTITION p_2025_q1 
    WITH TABLE sales_staging
    INCLUDING INDEXES
    WITHOUT VALIDATION;

-- パーティション情報の確認
SELECT table_name, partition_name, high_value, num_rows, blocks
FROM user_tab_partitions
WHERE table_name = 'SALES'
ORDER BY partition_position;

15. インデックス戦略

15.1 インデックスの種類

-- B-Tree インデックス(デフォルト、最も一般的)
CREATE INDEX idx_emp_dept ON employees(department_id);

-- 複合インデックス
CREATE INDEX idx_emp_dept_job ON employees(department_id, job_id);
-- 先頭カラムのみでもインデックスを使用可能
-- (department_id) or (department_id, job_id) の検索に有効

-- ユニークインデックス
CREATE UNIQUE INDEX idx_emp_email ON employees(email);

-- Bitmap インデックス(DWH 向け、低カーディナリティのカラムに有効)
CREATE BITMAP INDEX idx_cust_region ON customers(region);
-- 注意: DML が多い OLTP 環境では非推奨(ロック競合の原因)

-- 関数ベースインデックス
CREATE INDEX idx_emp_upper_name ON employees(UPPER(last_name));
-- SELECT * FROM employees WHERE UPPER(last_name) = 'SMITH';

-- 逆キーインデックス(RAC 環境でのインデックス競合回避)
CREATE INDEX idx_order_seq ON orders(order_id) REVERSE;

-- 部分インデックス(特定パーティションのみ)
CREATE INDEX idx_sales_amount ON sales(amount) LOCAL;
-- LOCAL: パーティションごとに個別のインデックス

-- グローバルインデックス
CREATE INDEX idx_sales_cust ON sales(customer_id) GLOBAL
    PARTITION BY RANGE (customer_id) (
        PARTITION p1 VALUES LESS THAN (10000),
        PARTITION p2 VALUES LESS THAN (20000),
        PARTITION p3 VALUES LESS THAN (MAXVALUE)
    );

-- Invisible インデックス(オプティマイザには見えないが維持される)
CREATE INDEX idx_test ON employees(hire_date) INVISIBLE;
ALTER INDEX idx_test VISIBLE;

-- Compressed インデックス
CREATE INDEX idx_orders_status ON orders(status, order_date) COMPRESS 1;
-- 先頭 1 カラムの重複値を圧縮

15.2 インデックスの監視と管理

-- インデックスの使用状況監視(12c 以降)
SELECT owner, index_name, table_name, monitoring, used
FROM v$object_usage;

-- インデックスの統計情報
SELECT index_name, blevel, leaf_blocks, distinct_keys, 
       avg_leaf_blocks_per_key, avg_data_blocks_per_key,
       clustering_factor, num_rows
FROM user_indexes
WHERE table_name = 'EMPLOYEES';

-- インデックスの再構築
ALTER INDEX idx_emp_dept REBUILD ONLINE PARALLEL 4;
ALTER INDEX idx_emp_dept NOPARALLEL;

-- インデックスの縮小(19c 以降)
ALTER INDEX idx_emp_dept COALESCE;

-- 未使用インデックスの確認
SELECT i.index_name, i.table_name, s.monitoring, s.used,
       s.start_monitoring, s.end_monitoring
FROM dba_indexes i
LEFT JOIN v$object_usage s ON i.index_name = s.index_name
WHERE i.owner = 'HR'
ORDER BY i.table_name, i.index_name;

16. セキュリティ

16.1 認証

-- データベース認証(デフォルト)
CREATE USER app_user IDENTIFIED BY "ComplexP@ss123!"
    DEFAULT TABLESPACE app_data
    TEMPORARY TABLESPACE temp
    QUOTA 10G ON app_data;

-- パスワードポリシー(プロファイル)
CREATE PROFILE secure_profile LIMIT
    FAILED_LOGIN_ATTEMPTS 5
    PASSWORD_LIFE_TIME 90
    PASSWORD_REUSE_TIME 365
    PASSWORD_REUSE_MAX 12
    PASSWORD_LOCK_TIME 1/24    -- 1 時間ロック
    PASSWORD_GRACE_TIME 7
    PASSWORD_VERIFY_FUNCTION ora12c_verify_function;

ALTER USER app_user PROFILE secure_profile;

-- OS 認証
CREATE USER ops$oracle IDENTIFIED EXTERNALLY;

-- Kerberos 認証
-- sqlnet.ora に設定
-- SQLNET.AUTHENTICATION_SERVICES = (KERBEROS5)

16.2 認可(権限管理)

-- システム権限
GRANT CREATE SESSION, CREATE TABLE, CREATE VIEW TO app_user;

-- オブジェクト権限
GRANT SELECT, INSERT, UPDATE ON hr.employees TO app_user;
GRANT EXECUTE ON hr.emp_pkg TO app_user;

-- ロール
CREATE ROLE app_readonly;
GRANT SELECT ANY TABLE TO app_readonly;  -- 注意: 広すぎる権限
-- より安全:
GRANT SELECT ON hr.employees TO app_readonly;
GRANT SELECT ON hr.departments TO app_readonly;
GRANT app_readonly TO report_user;

-- 最小権限の原則
-- DBA ロールは本番では使わない
-- SYSDBA 接続は緊急時のみ

16.3 監査

-- 統合監査(12c 以降、推奨)
CREATE AUDIT POLICY login_audit_policy
    ACTIONS LOGON, LOGOFF;

CREATE AUDIT POLICY dml_audit_policy
    ACTIONS INSERT ON hr.employees,
            UPDATE ON hr.employees,
            DELETE ON hr.employees;

CREATE AUDIT POLICY priv_audit_policy
    PRIVILEGES CREATE USER, ALTER USER, DROP USER,
              GRANT ANY PRIVILEGE, GRANT ANY ROLE;

-- ポリシーの有効化
AUDIT POLICY login_audit_policy;
AUDIT POLICY dml_audit_policy;
AUDIT POLICY priv_audit_policy;

-- 監査ログの確認
SELECT event_timestamp, dbusername, action_name, 
       object_schema, object_name, sql_text
FROM unified_audit_trail
WHERE event_timestamp > SYSTIMESTAMP - INTERVAL '1' DAY
ORDER BY event_timestamp DESC
FETCH FIRST 50 ROWS ONLY;

-- 監査ログのパージ
BEGIN
    DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(
        audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
        last_archive_time => SYSTIMESTAMP - INTERVAL '90' DAY
    );
    DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(
        audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
        use_last_arch_timestamp => TRUE
    );
END;
/

16.4 データ暗号化

-- Transparent Data Encryption (TDE)
-- ウォレット(キーストア)のセットアップ
ADMINISTER KEY MANAGEMENT CREATE KEYSTORE '/u01/app/oracle/admin/orcl/wallet' 
    IDENTIFIED BY "WalletP@ss123!";

ADMINISTER KEY MANAGEMENT SET KEYSTORE OPEN 
    IDENTIFIED BY "WalletP@ss123!";

ADMINISTER KEY MANAGEMENT SET KEY 
    IDENTIFIED BY "WalletP@ss123!" WITH BACKUP;

-- テーブルスペース暗号化(推奨)
CREATE TABLESPACE secure_data
    DATAFILE '/u02/oradata/orcl/secure_data01.dbf' SIZE 10G
    ENCRYPTION USING 'AES256'
    DEFAULT STORAGE(ENCRYPT);

-- カラムレベルの暗号化
CREATE TABLE sensitive_data (
    id          NUMBER,
    name        VARCHAR2(100),
    ssn         VARCHAR2(11) ENCRYPT USING 'AES256',
    credit_card VARCHAR2(19) ENCRYPT USING 'AES256' NO SALT
);

-- 自動ログインウォレット(パスワードなしでオープン)
ADMINISTER KEY MANAGEMENT CREATE AUTO_LOGIN KEYSTORE FROM KEYSTORE 
    '/u01/app/oracle/admin/orcl/wallet' 
    IDENTIFIED BY "WalletP@ss123!";

16.5 ネットワーク暗号化

-- sqlnet.ora(サーバー側)
SQLNET.ENCRYPTION_SERVER = REQUIRED
SQLNET.ENCRYPTION_TYPES_SERVER = (AES256)
SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA256)

-- sqlnet.ora(クライアント側)
SQLNET.ENCRYPTION_CLIENT = REQUIRED
SQLNET.ENCRYPTION_TYPES_CLIENT = (AES256)
SQLNET.CRYPTO_CHECKSUM_CLIENT = REQUIRED
SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT = (SHA256)

16.6 Virtual Private Database (VPD)

-- 行レベルセキュリティの実装
CREATE OR REPLACE FUNCTION sales_vpd_policy (
    p_schema IN VARCHAR2,
    p_table  IN VARCHAR2
) RETURN VARCHAR2 AS
BEGIN
    IF SYS_CONTEXT('USERENV', 'SESSION_USER') = 'ADMIN' THEN
        RETURN NULL;  -- 全行参照可能
    ELSE
        RETURN 'region = SYS_CONTEXT(''USERENV'', ''CLIENT_INFO'')';
    END IF;
END;
/

BEGIN
    DBMS_RLS.ADD_POLICY(
        object_schema   => 'SALES',
        object_name     => 'ORDERS',
        policy_name     => 'sales_region_policy',
        function_schema => 'SECURITY',
        policy_function => 'sales_vpd_policy',
        statement_types => 'SELECT, INSERT, UPDATE, DELETE'
    );
END;
/

17. パフォーマンスチューニング

17.1 パフォーマンス診断の基本

-- トップ待機イベント(最初に確認すべき)
SELECT event, total_waits, time_waited_micro/1000000 AS time_sec,
       ROUND(time_waited_micro/NULLIF(total_waits,0)/1000, 2) AS avg_wait_ms
FROM v$system_event
WHERE wait_class <> 'Idle'
ORDER BY time_waited_micro DESC
FETCH FIRST 20 ROWS ONLY;

-- 現在アクティブなセッション
SELECT s.sid, s.serial#, s.username, s.program, s.status,
       s.event, s.wait_class, s.seconds_in_wait,
       s.sql_id, sq.sql_text
FROM v$session s
LEFT JOIN v$sql sq ON s.sql_id = sq.sql_id AND s.sql_child_number = sq.child_number
WHERE s.type = 'USER' AND s.status = 'ACTIVE'
ORDER BY s.seconds_in_wait DESC;

17.2 主要な待機イベントと対策

待機イベント原因対策
db file sequential readシングルブロック読み取り(インデックススキャン)インデックス最適化、Buffer Cache 拡大
db file scattered readマルチブロック読み取り(フルスキャン)パーティショニング、統計情報更新
log file syncCOMMIT 時の REDO ログ書き込み待ちCOMMIT 頻度削減、Redo Log を高速ストレージに
log file parallel writeLGWR の Redo ログ書き込みストレージ性能改善
enq: TX - row lock contention行ロック競合アプリケーションロジック見直し
latch: shared poolShared Pool のラッチ競合バインド変数使用、Shared Pool 拡大
gc buffer busyRAC の Cache Fusion 待ちデータアフィニティの改善
direct path read/writeパラレルクエリ / ソートのディスク I/OPGA 拡大、TEMP テーブルスペース拡大

17.3 SQL チューニング

-- SQL の実行統計(V$SQL)
SELECT sql_id, plan_hash_value, executions, 
       ROUND(elapsed_time/1000000, 2) AS elapsed_sec,
       ROUND(elapsed_time/NULLIF(executions,0)/1000, 2) AS avg_ms,
       buffer_gets, disk_reads,
       ROUND(buffer_gets/NULLIF(executions,0)) AS gets_per_exec,
       rows_processed
FROM v$sql
WHERE parsing_schema_name = 'HR'
  AND executions > 0
ORDER BY elapsed_time DESC
FETCH FIRST 20 ROWS ONLY;

-- SQL Monitor(リアルタイム監視)
SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(
    sql_id       => '4q3z7r8k5g6h2',
    type         => 'TEXT',
    report_level => 'ALL'
) FROM dual;

-- SQL Tuning Advisor
DECLARE
    l_task VARCHAR2(64);
BEGIN
    l_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(
        sql_id      => '4q3z7r8k5g6h2',
        scope       => DBMS_SQLTUNE.SCOPE_COMPREHENSIVE,
        time_limit  => 300,
        task_name   => 'tune_sql_001'
    );
    DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => 'tune_sql_001');
END;
/

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('tune_sql_001') FROM dual;

17.4 I/O チューニング

-- データファイルごとの I/O 統計
SELECT name, phyrds, phywrts, readtim, writetim,
       ROUND(readtim/NULLIF(phyrds,0)*10, 2) AS avg_read_ms,
       ROUND(writetim/NULLIF(phywrts,0)*10, 2) AS avg_write_ms
FROM v$filestat f JOIN v$datafile d ON f.file# = d.file#
ORDER BY readtim + writetim DESC;

-- セグメントレベルの I/O 統計(最もI/Oが多いオブジェクト)
SELECT owner, object_name, object_type, statistic_name, value
FROM v$segment_statistics
WHERE statistic_name IN ('physical reads', 'physical writes', 'logical reads')
  AND value > 10000
ORDER BY value DESC
FETCH FIRST 20 ROWS ONLY;

17.5 メモリチューニング

-- SGA コンポーネントのサイズ推移(AWR から)
SELECT snap_id, name, ROUND(bytes/1024/1024) AS mb
FROM dba_hist_sgastat
WHERE snap_id IN (
    SELECT snap_id FROM dba_hist_snapshot 
    WHERE begin_interval_time > SYSDATE - 1
)
AND name IN ('buffer_cache', 'shared_io_pool', 'large_pool', 'java_pool', 'shared_pool')
ORDER BY snap_id, name;

-- SGA アドバイザー
SELECT size_for_estimate AS mb,
       size_factor,
       estd_physical_read_factor AS read_factor,
       estd_physical_reads
FROM v$sga_target_advice
ORDER BY size_for_estimate;

-- PGA アドバイザー
SELECT pga_target_for_estimate/1024/1024 AS target_mb,
       pga_target_factor AS factor,
       estd_extra_bytes_rw/1024/1024 AS extra_rw_mb,
       estd_pga_cache_hit_percentage AS cache_hit_pct,
       estd_overalloc_count
FROM v$pga_target_advice
ORDER BY pga_target_for_estimate;

18. 自動化機能 — AWR / ADDM / SQL Tuning Advisor

18.1 Automatic Workload Repository (AWR)

AWR はデータベースの性能統計を定期的にスナップショットとして収集・保存する機能である(デフォルト 1 時間ごと、8 日間保持)。

-- AWR スナップショット設定の確認
SELECT snap_interval, retention 
FROM dba_hist_wr_control;

-- スナップショット間隔と保持期間の変更
EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
    retention => 30 * 24 * 60,   -- 30 日(分単位)
    interval  => 30              -- 30 分間隔
);

-- 手動スナップショット
EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;

-- スナップショット一覧
SELECT snap_id, begin_interval_time, end_interval_time 
FROM dba_hist_snapshot 
ORDER BY snap_id DESC
FETCH FIRST 20 ROWS ONLY;

-- AWR レポートの生成(HTML)
-- 方法 1: SQL*Plus スクリプト
-- @?/rdbms/admin/awrrpt.sql

-- 方法 2: PL/SQL
SELECT output 
FROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_HTML(
    l_dbid     => (SELECT dbid FROM v$database),
    l_inst_num => 1,
    l_bid      => 100,   -- 開始スナップショット ID
    l_eid      => 105    -- 終了スナップショット ID
));

-- AWR レポートの主要セクション:
-- 1. Load Profile: DB Time, Redo size, Logical reads 等の負荷指標
-- 2. Top 5 Timed Events: 最も時間を消費した待機イベント
-- 3. SQL Statistics: トップ SQL(Elapsed Time, CPU, I/O 順)
-- 4. Instance Activity Stats: 詳細な統計カウンター

18.2 Active Session History (ASH)

AWR のリアルタイム版。1 秒ごとにアクティブセッションのサンプリングを行う。

-- 直近のアクティブセッション(V$ACTIVE_SESSION_HISTORY)
SELECT sample_time, session_id, session_serial#, 
       sql_id, event, wait_class, 
       session_state,  -- ON CPU / WAITING
       blocking_session, current_obj#,
       program, module, action
FROM v$active_session_history
WHERE sample_time > SYSTIMESTAMP - INTERVAL '15' MINUTE
ORDER BY sample_time DESC;

-- 過去の特定時間帯の分析(DBA_HIST_ACTIVE_SESS_HISTORY)
SELECT sql_id, event, wait_class, 
       COUNT(*) AS sample_count,
       ROUND(COUNT(*) * 100 / SUM(COUNT(*)) OVER(), 2) AS pct
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN 
    TO_TIMESTAMP('2025-03-15 14:00:00', 'YYYY-MM-DD HH24:MI:SS') AND
    TO_TIMESTAMP('2025-03-15 15:00:00', 'YYYY-MM-DD HH24:MI:SS')
  AND session_type = 'FOREGROUND'
GROUP BY sql_id, event, wait_class
ORDER BY sample_count DESC
FETCH FIRST 20 ROWS ONLY;

-- ASH レポート生成
-- @?/rdbms/admin/ashrpt.sql

18.3 Automatic Database Diagnostic Monitor (ADDM)

AWR スナップショットを分析し、パフォーマンス問題の根本原因と推奨事項を自動生成する。

-- ADDM レポートの表示
-- @?/rdbms/admin/addmrpt.sql

-- 直近の ADDM 結果
SELECT finding_id, type, message
FROM dba_addm_findings
WHERE task_name = (
    SELECT task_name FROM dba_addm_tasks
    ORDER BY creation_date DESC FETCH FIRST 1 ROW ONLY
)
ORDER BY impact DESC;

-- 手動 ADDM 実行
DECLARE
    l_task VARCHAR2(64);
BEGIN
    l_task := 'ADDM_' || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS');
    DBMS_ADVISOR.CREATE_TASK('ADDM', l_task);
    DBMS_ADVISOR.SET_TASK_PARAMETER(l_task, 'START_SNAPSHOT', 100);
    DBMS_ADVISOR.SET_TASK_PARAMETER(l_task, 'END_SNAPSHOT', 105);
    DBMS_ADVISOR.EXECUTE_TASK(l_task);
END;
/

18.4 SQL Plan Management (SPM)

実行計画の安定性を保証する機能。

-- SQL Plan Baseline の自動キャプチャ
ALTER SYSTEM SET optimizer_capture_sql_plan_baselines = TRUE SCOPE=BOTH;

-- 特定 SQL の計画を固定
DECLARE
    l_plans PLS_INTEGER;
BEGIN
    l_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(
        sql_id          => '4q3z7r8k5g6h2',
        plan_hash_value => 1234567890,
        fixed           => 'YES',
        enabled         => 'YES'
    );
    DBMS_OUTPUT.PUT_LINE('Loaded ' || l_plans || ' plan(s)');
END;
/

-- Baseline の確認
SELECT sql_handle, plan_name, enabled, accepted, fixed,
       optimizer_cost, elapsed_time, executions
FROM dba_sql_plan_baselines
ORDER BY last_modified DESC
FETCH FIRST 20 ROWS ONLY;

-- Baseline の発展(新計画の自動テスト)
DECLARE
    l_report CLOB;
BEGIN
    l_report := DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(
        sql_handle => 'SQL_abcdef1234567890',
        verify     => 'YES',
        commit     => 'YES'
    );
    DBMS_OUTPUT.PUT_LINE(l_report);
END;
/

18.5 自動インデックス作成(21c 以降)

-- 自動インデックスの有効化
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE', 'IMPLEMENT');
-- REPORT ONLY: レポートのみ、実装しない
-- IMPLEMENT: 自動的にインデックスを作成・削除

-- 自動インデックスの状態確認
SELECT * FROM dba_auto_index_config;

-- 自動インデックスのレポート
SELECT DBMS_AUTO_INDEX.REPORT_ACTIVITY(
    type          => 'TEXT',
    section       => 'ALL',
    report_level  => 'ALL'
) FROM dual;

19. Oracle Net とネットワーク構成

19.1 Oracle Net の基本

Oracle Net は、クライアントとデータベースサーバー間の通信を管理するネットワーキング層である。

┌──────────┐                        ┌──────────────┐
│  Client  │     Oracle Net          │   Listener   │
│ (TNS)    │ ────────────────────►  │  (tnslsnr)   │
│          │                        │   Port 1521   │
└──────────┘                        └──────┬───────┘
                                           │
                                    ┌──────▼───────┐
                                    │   Database    │
                                    │   Instance    │
                                    └──────────────┘

19.2 リスナー構成 (listener.ora)

# $ORACLE_HOME/network/admin/listener.ora

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost.example.com)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

# 静的サービス登録(Data Guard / ASM で必要)
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = orcl.example.com)
      (ORACLE_HOME = /u01/app/oracle/product/19c/dbhome_1)
      (SID_NAME = orcl)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcl_DGMGRL.example.com)
      (ORACLE_HOME = /u01/app/oracle/product/19c/dbhome_1)
      (SID_NAME = orcl)
    )
  )

# リスナーのタイムアウト設定
INBOUND_CONNECT_TIMEOUT_LISTENER = 60
DIAG_ADR_ENABLED_LISTENER = ON
LOG_DIRECTORY_LISTENER = /u01/app/oracle/diag/tnslsnr/dbhost/listener/alert
LOG_FILE_LISTENER = log.xml
# リスナーの管理
lsnrctl start
lsnrctl stop
lsnrctl status
lsnrctl reload
lsnrctl services  # 登録されたサービス一覧

19.3 TNS 名解決 (tnsnames.ora)

# $ORACLE_HOME/network/admin/tnsnames.ora

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost.example.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl.example.com)
    )
  )

# タイムアウト設定付き
ORCL_TIMEOUT =
  (DESCRIPTION =
    (CONNECT_TIMEOUT = 10)
    (TRANSPORT_CONNECT_TIMEOUT = 5)
    (RETRY_COUNT = 3)
    (RETRY_DELAY = 3)
    (ADDRESS = (PROTOCOL = TCP)(HOST = dbhost.example.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl.example.com)
    )
  )

# RAC SCAN 接続
ORCL_RAC =
  (DESCRIPTION =
    (CONNECT_TIMEOUT = 10)(TRANSPORT_CONNECT_TIMEOUT = 5)
    (ADDRESS = (PROTOCOL = TCP)(HOST = orcl-scan.example.com)(PORT = 1521))
    (CONNECT_DATA =
      (SERVICE_NAME = app_service.example.com)
      (SERVER = DEDICATED)
    )
  )

19.4 sqlnet.ora

# $ORACLE_HOME/network/admin/sqlnet.ora

# 名前解決の優先順位
NAMES.DIRECTORY_PATH = (TNSNAMES, LDAP, EZCONNECT)

# タイムアウト設定
SQLNET.INBOUND_CONNECT_TIMEOUT = 60
SQLNET.RECV_TIMEOUT = 30
SQLNET.SEND_TIMEOUT = 30

# Dead Connection Detection(接続断検出)
SQLNET.EXPIRE_TIME = 10   -- 10 分ごとにプローブ送信

# バナー制限(セキュリティ)
SEC_USER_AUDIT_ACTION_BANNER = /u01/app/oracle/admin/orcl/banner.txt
SEC_USER_UNAUTHORIZED_ACCESS_BANNER = /u01/app/oracle/admin/orcl/warning.txt

# 接続元の制限
TCP.VALIDNODE_CHECKING = YES
TCP.INVITED_NODES = (192.168.1.0/24, 10.0.0.0/8, dbhost.example.com)
TCP.EXCLUDED_NODES = (192.168.1.100)

19.5 Easy Connect 構文

# 基本形式
sqlplus hr/password@dbhost:1521/orcl

# PDB への接続
sqlplus hr/password@dbhost:1521/pdb_sales

# Oracle 19c 拡張 Easy Connect
sqlplus hr/password@"dbhost:1521/orcl?connect_timeout=10&transport_connect_timeout=5&retry_count=3"

19.6 Connection Manager (CMAN)

# cman.ora - 中間プロキシとして動作
CMAN =
  (CONFIGURATION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = cman-host)(PORT = 1630))
    (RULE_LIST =
      (RULE = (SRC = 192.168.1.0/24)(DST = 10.0.0.0/8)(SRV = orcl)(ACT = ACCEPT))
      (RULE = (SRC = *)(DST = *)(SRV = *)(ACT = REJECT))
    )
    (PARAMETER_LIST =
      (MAX_CONNECTIONS = 1024)
      (IDLE_TIMEOUT = 60)
      (SESSION_TIMEOUT = 0)
      (MAX_GATEWAY_PROCESSES = 8)
    )
  )

20. GoldenGate 連携とレプリケーション

20.1 レプリケーション・オプションの比較

機能Data GuardGoldenGateStreams
レプリケーション方式REDO ベース(物理/論理)ログベース(論理)キャプチャ/アプライ
異機種間✓(Oracle 以外も対応)
双方向
リアルタイム
フィルタリング✗(全データ)✓(テーブル/行/カラム単位)
変換
推奨用途DR/HA異機種連携、移行、ETL非推奨(GoldenGate に移行)

20.2 Oracle Streams(レガシー)

注意: Oracle Streams は 12.2 で非推奨となり、GoldenGate への移行が推奨されている。

20.3 LogMiner

REDO ログからデータ変更を読み取るユーティリティ。トラブルシューティングや簡易なデータ復旧に使用。

-- LogMiner の使用例
BEGIN
    DBMS_LOGMNR.ADD_LOGFILE(
        logfilename => '/u01/oradata/orcl/redo01.log',
        options     => DBMS_LOGMNR.NEW
    );
    DBMS_LOGMNR.ADD_LOGFILE(
        logfilename => '/u01/archive/arch_1_100.arc',
        options     => DBMS_LOGMNR.ADDFILE
    );
    DBMS_LOGMNR.START_LOGMNR(
        options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG +
                   DBMS_LOGMNR.COMMITTED_DATA_ONLY
    );
END;
/

-- 変更内容の確認
SELECT scn, timestamp, operation, seg_name, sql_redo, sql_undo
FROM v$logmnr_contents
WHERE seg_owner = 'HR' AND seg_name = 'EMPLOYEES'
ORDER BY scn;

-- 終了
EXEC DBMS_LOGMNR.END_LOGMNR;

21. Oracle Cloud Infrastructure (OCI) 連携

21.1 OCI Database サービス

サービス説明
Bare Metal DB専用ベアメタルサーバー上の Oracle DB
VM DB System仮想マシン上の Oracle DB
Exadata Cloud Serviceクラウド上の Exadata(最高性能)
Autonomous Database (ADB)完全マネージドの自律型データベース
Autonomous Transaction Processing (ATP)OLTP ワークロード向け ADB
Autonomous Data Warehouse (ADW)DWH ワークロード向け ADB

21.2 Data Guard のクラウド連携

-- オンプレミス ↔ OCI のハイブリッド Data Guard
-- プライマリ: オンプレミス
-- スタンバイ: OCI

-- OCI 側の設定例(VPN / FastConnect 接続が前提)
ALTER SYSTEM SET log_archive_dest_2 = 
    'SERVICE=orcl_cloud LGWR ASYNC 
     VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) 
     DB_UNIQUE_NAME=orcl_cloud
     NET_TIMEOUT=30' 
    SCOPE=BOTH;

21.3 RMAN のクラウドバックアップ

-- OCI Object Storage へのバックアップ
-- Oracle Database Backup Cloud Service モジュールのインストール後

CONFIGURE CHANNEL DEVICE TYPE SBT_TAPE PARMS 
    'SBT_LIBRARY=/u01/app/oracle/product/19c/dbhome_1/lib/libopc.so,
     ENV=(OPC_PFILE=/u01/app/oracle/admin/orcl/opc_config.ora)';

BACKUP AS COMPRESSED BACKUPSET
    INCREMENTAL LEVEL 0
    DATABASE
    FORMAT 'db_%d_%T_%U'
    DEVICE TYPE SBT_TAPE
    TAG 'CLOUD_FULL';

21.4 Database Migration

# Oracle Zero Downtime Migration (ZDM)
# オンプレミスから OCI への移行ツール

# 論理移行(Data Pump)
expdp system/password@source \
    FULL=Y \
    DIRECTORY=dp_dir \
    DUMPFILE=full_export_%U.dmp \
    PARALLEL=4 \
    FILESIZE=10G \
    COMPRESSION=ALL \
    LOGFILE=full_export.log

impdp system/password@target \
    FULL=Y \
    DIRECTORY=dp_dir \
    DUMPFILE=full_export_%U.dmp \
    PARALLEL=4 \
    LOGFILE=full_import.log

# Data Pump の主要オプション
# SCHEMAS=HR,SALES          -- スキーマ単位
# TABLES=HR.EMPLOYEES       -- テーブル単位
# EXCLUDE=STATISTICS         -- 統計情報を除外
# REMAP_SCHEMA=HR:HR_NEW    -- スキーマ名の変更
# REMAP_TABLESPACE=TS1:TS2  -- テーブルスペースの変更
# TRANSFORM=SEGMENT_ATTRIBUTES:N  -- ストレージ属性を除外

22. 運用ベストプラクティス

22.1 日次運用チェックリスト

-- 1. アラートログの確認
-- $ORACLE_BASE/diag/rdbms/<db>/<sid>/trace/alert_<sid>.log
-- ORA- エラーの有無を確認

-- 2. テーブルスペース使用率
SELECT tablespace_name,
       ROUND(used_mb) AS used_mb,
       ROUND(max_mb) AS max_mb,
       ROUND(used_mb/max_mb * 100, 2) AS pct_used
FROM (
    SELECT ts.tablespace_name,
           SUM(df.bytes)/1024/1024 - SUM(NVL(fs.free_bytes,0))/1024/1024 AS used_mb,
           SUM(GREATEST(df.bytes, df.maxbytes))/1024/1024 AS max_mb
    FROM dba_tablespaces ts
    JOIN (SELECT tablespace_name, SUM(bytes) AS bytes, SUM(maxbytes) AS maxbytes 
          FROM dba_data_files GROUP BY tablespace_name) df 
        ON ts.tablespace_name = df.tablespace_name
    LEFT JOIN (SELECT tablespace_name, SUM(bytes) AS free_bytes 
               FROM dba_free_space GROUP BY tablespace_name) fs 
        ON ts.tablespace_name = fs.tablespace_name
    WHERE ts.contents <> 'TEMPORARY'
    GROUP BY ts.tablespace_name
)
WHERE used_mb/max_mb > 0.8  -- 80% 以上使用
ORDER BY pct_used DESC;

-- 3. RMAN バックアップの成功確認
SELECT session_key, start_time, end_time, status, 
       input_bytes_display, output_bytes_display,
       time_taken_display
FROM v$rman_backup_job_details
WHERE start_time > SYSDATE - 2
ORDER BY start_time DESC;

-- 4. Data Guard のステータス確認
SELECT database_role, protection_mode, protection_level,
       switchover_status
FROM v$database;

SELECT dest_id, status, error, gap_status
FROM v$archive_dest_status
WHERE dest_id <= 2;

-- 5. 無効なオブジェクトの確認
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE status = 'INVALID'
  AND owner NOT IN ('SYS', 'SYSTEM')
ORDER BY owner, object_type, object_name;

-- 無効なオブジェクトの再コンパイル
EXEC UTL_RECOMP.RECOMP_SERIAL('HR');
-- または
EXEC UTL_RECOMP.RECOMP_PARALLEL(4, 'HR');

22.2 定期メンテナンス

-- 統計情報の収集スケジュール確認
SELECT window_name, enabled, active, 
       next_start_date, duration
FROM dba_scheduler_windows
WHERE window_name LIKE '%MAINTENANCE%'
ORDER BY next_start_date;

-- メンテナンスウィンドウの変更
BEGIN
    DBMS_SCHEDULER.SET_ATTRIBUTE(
        name      => 'MONDAY_WINDOW',
        attribute => 'DURATION',
        value     => NUMTODSINTERVAL(6, 'HOUR')  -- 6 時間に拡張
    );
END;
/

-- テーブルの断片化確認と解消
SELECT table_name, 
       blocks * 8 / 1024 AS allocated_mb,
       num_rows * avg_row_len / 1024 / 1024 AS actual_mb,
       ROUND((1 - (num_rows * avg_row_len / NULLIF(blocks * 8 * 1024, 0))) * 100) AS waste_pct
FROM dba_tables
WHERE owner = 'HR'
  AND blocks > 100
  AND (1 - (num_rows * avg_row_len / NULLIF(blocks * 8 * 1024, 0))) > 0.3
ORDER BY blocks DESC;

-- オンラインでのテーブル縮小
ALTER TABLE hr.employees ENABLE ROW MOVEMENT;
ALTER TABLE hr.employees SHRINK SPACE CASCADE;  -- インデックスも含む

-- オンラインでのテーブル再編成(12c 以降)
ALTER TABLE hr.employees MOVE ONLINE;
-- インデックスの再構築は不要(ONLINE MOVE は自動的にインデックスを維持)

22.3 パッチ管理

# OPatch でのパッチ適用

# 現在のパッチレベル確認
$ORACLE_HOME/OPatch/opatch lspatches

# パッチ適用の手順(Release Update の例)
# 1. バックアップの取得
# 2. OPatch の最新化
unzip p6880880_190000_Linux-x86-64.zip -d $ORACLE_HOME

# 3. パッチの展開
unzip p12345678_190000_Linux-x86-64.zip -d /tmp/patches

# 4. 前提条件の確認
cd /tmp/patches/12345678
$ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./

# 5. DB の停止
srvctl stop database -d orcl

# 6. パッチ適用
$ORACLE_HOME/OPatch/opatch apply

# 7. DB の起動とデータディクショナリの更新
sqlplus / as sysdba
STARTUP
@?/rdbms/admin/catbundle.sql psu apply
@?/rdbms/admin/utlrp.sql

# 8. 確認
SELECT action_time, action, namespace, version, comments
FROM dba_registry_sqlpatch
ORDER BY action_time DESC;

22.4 Capacity Planning

-- データ増加率の分析
SELECT 
    TO_CHAR(begin_interval_time, 'YYYY-MM') AS month,
    tablespace_name,
    ROUND(AVG(tablespace_size) * ts.block_size / 1024 / 1024 / 1024, 2) AS avg_size_gb,
    ROUND(AVG(tablespace_usedsize) * ts.block_size / 1024 / 1024 / 1024, 2) AS avg_used_gb
FROM dba_hist_tbspc_space_usage h
JOIN dba_hist_snapshot s ON h.snap_id = s.snap_id
JOIN dba_tablespaces ts ON h.tablespace_id = ts.tablespace_name  -- 注: 実際は別の結合が必要
WHERE begin_interval_time > ADD_MONTHS(SYSDATE, -6)
GROUP BY TO_CHAR(begin_interval_time, 'YYYY-MM'), tablespace_name, ts.block_size
ORDER BY tablespace_name, month;

-- セグメントサイズのトップ 20
SELECT owner, segment_name, segment_type, tablespace_name,
       ROUND(bytes/1024/1024/1024, 2) AS gb
FROM dba_segments
WHERE owner NOT IN ('SYS', 'SYSTEM')
ORDER BY bytes DESC
FETCH FIRST 20 ROWS ONLY;

23. トラブルシューティング

23.1 診断フレームワーク

Oracle 11g 以降、Automatic Diagnostic Repository (ADR) にすべての診断情報が統合されている。

# ADR のベースディレクトリ
echo $ORACLE_BASE/diag

# adrci(ADR Command Interpreter)
adrci
adrci> show homes
adrci> set home diag/rdbms/orcl/orcl
adrci> show alert -tail 50
adrci> show incident
adrci> show problem
adrci> ips create package incident 12345

23.2 よくあるエラーと対処法

-- ORA-01555: Snapshot too old
-- 原因: UNDO 領域不足でクエリの読み取り一貫性を維持できない
-- 対策:
ALTER SYSTEM SET undo_retention = 7200 SCOPE=BOTH;
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
-- UNDO テーブルスペースのサイズ拡大

-- ORA-04031: Unable to allocate shared memory
-- 原因: Shared Pool の断片化/枯渇
-- 対策:
ALTER SYSTEM SET shared_pool_size = 2G SCOPE=BOTH;
-- バインド変数の使用を促進
ALTER SYSTEM SET cursor_sharing = 'FORCE' SCOPE=BOTH;  -- 一時的な対処
ALTER SYSTEM FLUSH SHARED_POOL;  -- 最終手段

-- ORA-01653: Unable to extend table
-- 原因: テーブルスペースの容量不足
-- 対策:
ALTER TABLESPACE app_data ADD DATAFILE '/u02/oradata/orcl/app_data03.dbf' 
    SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE 50G;

-- ORA-00060: Deadlock detected
-- 診断: アラートログのトレースファイルでデッドロックグラフを確認
-- 対策: アプリケーションのロック取得順序を統一

-- ORA-12154: TNS:could not resolve the connect identifier
-- 診断:
-- tnsping orcl
-- 対策: tnsnames.ora の設定確認、リスナーの起動確認

-- ORA-28001: The password has expired
ALTER USER app_user IDENTIFIED BY "NewP@ssword123!";
-- パスワードポリシーの確認
SELECT resource_name, limit FROM dba_profiles 
WHERE profile = 'DEFAULT' AND resource_type = 'PASSWORD';

23.3 ハングと性能劣化の診断

-- Hang Analysis
-- oradebug を使用(SYS で接続)
ORADEBUG SETMYPID;
ORADEBUG HANGANALYZE 3;

-- V$WAIT_CHAINS(RAC 環境でも使用可能)
SELECT chain_id, chain_signature, instance, sid, 
       blocker_instance, blocker_sid,
       wait_event_text, in_wait_secs, sql_id
FROM v$wait_chains
WHERE chain_id > 0
ORDER BY chain_id, row_wait_obj#;

-- OS レベルの確認
-- CPU 使用率
-- ps -eo pid,ppid,pcpu,pmem,args --sort=-pcpu | head -20
-- メモリ使用率
-- free -g
-- ディスク I/O
-- iostat -xm 5 3

23.4 アラートログの監視スクリプト

#!/bin/bash
# alert_monitor.sh - アラートログの ORA- エラー監視

ALERT_LOG=$ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log
LAST_POS_FILE=/tmp/alert_monitor_pos.dat

# 前回の読み取り位置を取得
if [ -f $LAST_POS_FILE ]; then
    LAST_POS=$(cat $LAST_POS_FILE)
else
    LAST_POS=0
fi

# 現在のファイルサイズ
CURRENT_SIZE=$(wc -c < $ALERT_LOG)

# 新しい部分のみチェック
if [ $CURRENT_SIZE -gt $LAST_POS ]; then
    ERRORS=$(tail -c +$((LAST_POS + 1)) $ALERT_LOG | grep -i "ORA-" | grep -v "ORA-00000")
    if [ -n "$ERRORS" ]; then
        echo "$ERRORS" | mail -s "Oracle Alert: ORA errors detected" dba@example.com
    fi
fi

# 位置を更新
echo $CURRENT_SIZE > $LAST_POS_FILE

24. まとめ

24.1 Oracle Database の強み

  • エンタープライズ級の信頼性: 数十年の実績に裏打ちされた堅牢なトランザクション処理
  • 包括的な HA/DR: Data Guard、RAC、Application Continuity による多層的な可用性
  • 高度な自動化: AWR/ADDM/SQL Tuning Advisor による自動診断と最適化
  • マルチテナント: CDB/PDB による効率的なデータベース統合
  • セキュリティ: TDE、VPD、統合監査、データリダクションによる包括的なデータ保護

24.2 運用上の重要ポイント

  1. バックアップは命綱: RMAN の増分バックアップ + アーカイブログを確実に取得
  2. 統計情報を最新に保つ: CBO の正確な判断には最新の統計情報が不可欠
  3. 監視の自動化: アラートログ、テーブルスペース使用率、パフォーマンス指標の定期監視
  4. パッチ適用の計画: セキュリティパッチと Release Update を定期的に適用
  5. キャパシティプランニング: データ増加率のトレンド分析と先行投資

24.3 バージョン選択の指針

要件推奨バージョン
安定性重視の本番環境19c(長期サポート、2027 年まで Premier Support)
最新機能を検証23ai(AI Vector Search、JSON Duality)
クラウドマネージドAutonomous Database(最新パッチ自動適用)

24.4 参考リソース


免責事項: 本ドキュメントは教育・参考目的で作成されたものであり、すべての環境に適用できるものではない。実際の構成・運用においては、Oracle の公式ドキュメントおよび My Oracle Support を参照されたい。

最終更新: 2026 年 4 月