忍者ブログ
データベースエンジニアのための実践ブログ。Oracle・PostgreSQL・MySQLなどの環境構築、実行計画の読み方やチューニングといった現場で役立つノウハウ、DB基礎知識までを発信しています。

【データベースの基礎】データ損失を防ぐ生命線!「ログ先行書き込み(WAL / コミットログ)」の仕組みと役割

データベースシステムにおいて、障害が発生してもデータを安全に復旧(リカバリー)できるのはなぜだろうか。
その中心にあるメカニズムが「ログ先行書き込み(WAL: Write-Ahead Logging)」(あるいはコミットログ)である。

今回は、ログ先行書き込みの基本的な概念から、その必要性、内部の仕組み、代表的な採用製品、そしてメリット・デメリットまでをわかりやすく整理した。


1. ログ先行書き込み(WAL)とは?基本概念

データベースでは、パフォーマンスを向上させるために、変更されたデータ(更新内容)をまず高速なメモリ(バッファ)上で処理し、実際のストレージ(ディスク)への書き込みは後回し(遅延書き込み)にしている。

しかし、ディスクに書き込まれる前にサーバーの電源が落ちたり障害が発生したりすると、メモリ上のデータは消えてしまう。
これを防ぐため、「データ本体をディスクに書き込む前に、変更履歴(ログ)を必ず安全なストレージに順次書き込んでおく」という仕組みがWALである。


2. なぜWALが必要なのか?(仕組みと目的)

データベースの信頼性を保つ上で、WALには主に2つの重要な目的がある。

  • ① クラッシュリカバリー(障害からの復旧)
    突然のサーバーダウン時、ディスク上のデータファイルは中途半端な状態になっている可能性がある。このときWAL(変更ログ)を参照し、未完了の処理をロールバックしたり、完了していてディスクに反映されていなかった処理を再適用(リドゥ)することで、データを一貫性のある正しい状態に戻す。
  • ② トランザクションの耐久性(Durability)保証
    ACID特性の「D(Durability)」を担保する。アプリケーションが「コミット(保存)」を要求した際、重いデータファイルを直接ディスクに書き込むのではなく、軽量なログ領域へ確実に書き終えた時点で「保存完了」と応答できるため、高速かつ安全な処理が可能になる。

3. どんな製品で採用されている?(Oracleとの違い)

「WAL」という名称や概念は、多くのオープンソースデータベースや分散データベースで標準的に採用されている。

  • ・PostgreSQL: そのまま「WAL(Write-Ahead Log)」と呼ばれる仕組みで実装されており、アーキテクチャの根幹をなしている。
  • ・SQLite: 「WALモード」を有効にすることで、並行処理性能と安全性を飛躍的に向上させることができる。
  • ・MySQL (InnoDB): 「Redoログ(Redo Log)」と呼ばれる仕組みを採用しており、概念としてはWALと同等である。

Oracle Databaseの場合は?

質問にもある通り、Oracle Databaseでは「WAL」という用語は一般的に使われない。代わりに、同様の目的を持つ仕組みとして「Redoログ(Redo Log / Redoログファイル)」や、変更ベクトルを管理する「LGWR(ログライター)プロセス」が稼働している。用語やアーキテクチャの表現は異なるが、「変更を先にログへ書き込んでからデータファイルを更新する」という根本的な思想は同一である。


4. WALのメリット・デメリット

メリット
  • 書き込みパフォーマンスの向上: ランダムアクセスとなる重いデータファイルの更新を遅延させ、シーケンシャルにログへ追記することでI/Oを高速化できる。
  • 高い信頼性と復旧力: 突然の電源断やクラッシュがあっても、ログから正確にデータを復元できる。
  • レプリケーションへの応用: ログをそのままスタンバイサーバーへ転送・適用することで、手軽に高可用性(HA)構成や読み取り専用レプリカを構築できる。
デメリット・注意点
  • ストレージ容量の圧迫: 更新が頻繁なシステムではログが急速に肥大化するため、適切なローテーションや定期的なバックアップ(アーカイブ)が不可欠。
  • I/Oボトルネックの懸念: コミットのたびにログの物理的なディスク書き込み(フラッシュ)を待つため、ストレージの書き込み性能(特にIOPSやレイテンシ)が全体の性能を大きく左右する。

5. まとめ

ログ先行書き込み(WAL / Redoログ)は、データベースの「スピード」と「安全性」を両立させるための最も重要なアーキテクチャである。
普段何気なく発行している COMMIT の裏側では、このログへの書き込みが確実に行われることで、私たちのデータが守られている。

【エンジニアの押さえどころ】
✔ データ本体の書き込みよりも「ログへの書き込み」が先に行われる(これがWALの名前の由来)。
✔ PostgreSQLなどのOSSでは「WAL」、Oracleでは「Redoログ」と呼ばれるが、果たす役割は同じ。
✔ トランザクション性能や障害復旧をチューニングする際は、ログ出力先ストレージのパフォーマンスが鍵となる。
PR

【Oracle 26ai/23ai】11gからのステップアップ!Oracleマルチテナント(CDB/PDB)完全ガイド

Oracle Database 12c以降から導入され、現代のOracle環境(23ai/26aiなど)における標準アーキテクチャとなった「マルチテナント(CDB/PDB)」。
従来の非マルチテナント(非CDB)環境に慣れ親しんだエンジニアにとって、CDBとPDBの関係性や運用方法の違いは最初に押さえておきたい重要ポイントである。

今回は、マルチテナントアーキテクチャの基本概念から接続方法、バックアップ、リスナー、リソース制御までの全体像をわかりやすく整理した。


1. CDBとPDBの基本概念

Oracleのマルチテナント構造は、よく「分譲マンション」に例えると構造を掴みやすくなる。

  • CDB (Container Database) = マンションの建物・管理室・共有設備
    メモリ(SGA/PGA)やバックグラウンドプロセスなどの共通リソースを保持し、システム全体を管理・監視する「親データベース」。
  • PDB (Pluggable Database) = マンションの各部屋(専有スペース)
    業務データやテーブルを個別に保持する独立した「子データベース」。お互いの PDB は完全に分離されている。

CDB と PDB の役割比較

比較項目CDB (Container Database)PDB (Pluggable Database)
役割 システム全体のリソース管理・共通基盤 アプリケーションデータの格納・実行
主な利用者 データベース管理者(DBA) アプリケーション開発者・一般ユーザー
接続用途 DB全体の保守・監視・バックアップ Webアプリや外部ツールからのデータ操作

2. アプリケーションからの接続

Java、Python、あるいは DBeaver などの外部開発ツールから接続する場合、原則として「PDB へ接続」することが基本となる。

【接続先の指定例】
・業務アプリ利用:localhost:1521/FREEPDB1 (PDBのサービス名)
・全体管理作業:localhost:1521/FREE (CDBのサービス名)

環境の隔離:
1つの CDB 上に開発用 PDB(DEV_PDB)と検証用 PDB(TEST_PDB)を独立して同居させることが可能。

3. バックアップと運用の単位

マルチテナント環境では、目的に応じてバックアップの粒度を柔軟に選択できる。

  • CDB単位(全体物理バックアップ)
    RMAN を使用し、全 PDB を含めた CDB 全体を一括バックアップ。サーバー全体の障害対策やインフラ移行に適している。
  • PDB単位(個別物理リカバリ・複製)
    特定の PDB のみを停止・バックアップ・復元。稼働中の他 PDB に影響を与えずに、PDB の複製(Clone)や別 CDB への移植(Plug/Unplug)が可能。
  • 論理バックアップ
    expdp / impdp を使い、特定の PDB やスキーマ単位でデータをダンプファイルとして抽出する。

4. リスナーとの対応関係

リスナーは CDB(サーバー・インスタンス)単位で 1 つ存在 する。
マンションで言えば「エントランスの総合受付(コンシェルジュ)」である。各 PDB ごとに個別リスナーが存在するわけではなく、1 つのリスナーがポート 1521 への通信を一括受領する。

[アプリ / クライアント] ──(Port 1521)──> [ リスナー (受付) ]
                                              │
                    ┌─────────────────────────┴─────────────────────────┐
                    ▼ (サービス名: FREE)                                 ▼ (サービス名: FREEPDB1)
             ┌──────────────┐                                    ┌──────────────┐
             │  CDB (FREE)  │                                    │ PDB(FREEPDB1)│
             └──────────────┘                                    └──────────────┘

クライアントから渡された「サービス名」をリスナーが判定し、該当する CDB や PDB へルーティングする。PDB を追加した場合も、DB が自動でサービス名をリスナーへ登録するため、リスナーの再設定は不要となっている。


5. CDBによる一元リソース制御

各 PDB への CPU、メモリ、I/O、ストレージなどのリソース割り当ては、親である CDB が 一元管理 する。
マンションの管理組合(CDB)が各部屋(PDB)の使用上限を決める仕組みであり、主に以下の方法で制御を行う。

  • CPU / I/O 制御(CDBリソース・マネージャ)
    PDB ごとに CPU の最低保証割合(Shares)や最大使用上限(Utilization Limit)を設定できる。
  • メモリ・ストレージ制御
    PDB ごとに初期化パラメータで SGA/PGA の利用限度額を指定するほか、PDB の最大ディスク容量(MAX_SIZE)を設定可能。

この設定により、特定の PDB で重い処理が発生した際にも他の PDB が巻き添えで低速化する「ノイジー・ネイバー(うるさい隣人)問題」を効果的に防止することができる。

【11g経験者が押さえるべきマルチテナントの勘所】
✔ 接続時は従来のSID指定だけでなく、PDBの「サービス名(例: FREEPDB1)」を指定してルーティングする。
✔ CDB全体の管理(バックアップやインスタンス起動)と、PDB個別の操作(スキーマ・データ操作)を明確に意識する。
✔ 複数テナント集約時のリソース競合は「CDBリソース・マネージャ」でスマートに制御する。

【Oracle 26ai】RHEL 10環境へ「Oracle AI Database 26ai Free」をネイティブ導入する

最新の次世代データベースである「Oracle AI Database 26ai Free」を、完全無料のRHEL 10互換環境(CentOS Stream 10やAlmaLinux 10など)にRPMで直接インストール(ネイティブ導入)するための手順をまとめた。

RHEL 10世代では、専用の事前準備パッケージ(Preinstall RPM)や本体パッケージが公式に提供されており、手順に沿って進めることでスムーズに最新のAIデータベース環境を構築できる。


【前提条件】

  • 作業は sudo 権限を持つユーザー(または root ユーザー)で実施すること。
  • サーバーがインターネットに接続でき、標準のリポジトリから依存パッケージを取得できること。

1. パッケージのダウンロードとサーバーへの配置

Oracle 26ai Free をインストールするためには、以下の2つの RPM ファイルを RHEL 10 サーバー上の任意の作業ディレクトリ(例: /tmp)に配置する。

  • ・事前準備 RPM: oracle-ai-database-preinstall-26ai-1.0-1.el10.x86_64.rpm
  • ・データベース本体 RPM: oracle-ai-database-free-26ai-23.26.2-1.el10.x86_64.rpm

パターンA: サーバー上で直接ダウンロードする場合(推奨)

# 作業ディレクトリに移動
cd /tmp

# 事前準備(Preinstall)パッケージのダウンロード
curl -O https://yum.oracle.com/repo/OracleLinux/OL10/appstream/x86_64/getPackage/oracle-ai-database-preinstall-26ai-1.0-1.el10.x86_64.rpm

# Oracle 26ai Free 本体パッケージのダウンロード
curl -O https://download.oracle.com/otn-pub/otn_software/db-free/oracle-ai-database-free-26ai-23.26.2-1.el10.x86_64.rpm

※ダウンロード先 URL は Oracle の公開仕様に基づきます。

パターンB: 手元のPCでダウンロード済みのファイルを転送する場合

すでに Windows や Mac のブラウザでダウンロード済みの場合は、SCP クライアント等を使って RHEL 10 サーバーへ転送する。

# (例) Mac/Linux などの手元のPCからコマンドで転送する場合
scp oracle-ai-database-preinstall-26ai-1.0-1.el10.x86_64.rpm [ユーザー名]@[サーバーのIPアドレス]:/tmp/
scp oracle-ai-database-free-26ai-23.26.2-1.el10.x86_64.rpm [ユーザー名]@[サーバーのIPアドレス]:/tmp/

2. 依存パッケージと事前設定 RPM のインストール

ファイルがあるディレクトリに移動し、Preinstall パッケージをインストールする。これにより、必要な依存関係の解決、OS ユーザー(oracle)の自動作成、カーネルパラメータの自動チューニングが行われる。

cd /tmp

# 事前準備パッケージのインストール
sudo dnf install -y ./oracle-ai-database-preinstall-26ai-1.0-1.el10.x86_64.rpm

3. Oracle 26ai Free 本体 RPM のインストール

続いて、データベース本体の RPM ファイルをインストールする。

# データベース本体のインストール
sudo dnf localinstall -y ./oracle-ai-database-free-26ai-23.26.2-1.el10.x86_64.rpm

4. データベースの構築・初期設定

インストールが完了したら、構成スクリプトを実行してデータベースを作成する。この手順で SYS / SYSTEM / PDBADMIN ユーザー共通の管理用パスワードを設定する。

# 構成スクリプトの実行
sudo /etc/init.d/oracle-free-26ai configure
【注意事項】
・スクリプト実行中、パスワードの入力を求められます。
・セキュリティ要件として、8文字以上で、大文字・小文字・数字をすべて含むパスワードを入力してください(入力した文字は画面に表示されません)。

データベースの作成が完了すると、以下のようなメッセージとログ出力先が表示される。

データベース情報:
グローバル・データベース名: FREE
システム識別子(SID): FREE
詳細はログ・ファイル "/opt/oracle/cfgtoollogs/dbca/FREE/FREE.log" を参照してください。

Connect to Oracle AI Database using one of the connect strings:
    Pluggable database: oracle26ai-server/FREEPDB1
    Multitenant container database: oracle26ai-server

5. 環境変数の設定

今後データベースの操作を行うユーザー(OS の oracle ユーザーや作業ユーザーなど)のプロファイル(~/.bash_profile)に環境変数を追加する。

# bash_profile に環境変数を明示的に追記
cat << 'EOF' >> ~/.bash_profile

# Oracle Database Environment Variables
export ORACLE_SID=FREE
export ORACLE_BASE=/opt/oracle
export ORACLE_HOME=/opt/oracle/product/26ai/dbhomeFree
export PATH=$ORACLE_HOME/bin:$PATH

# 日本語環境用の文字コード設定 (文字化け防止)
export NLS_LANG=Japanese_Japan.AL32UTF8
EOF

# 設定を現在のセッションに反映
source ~/.bash_profile

6. 動作確認・接続テスト

OS のコマンドラインから SQL*Plus を利用して、データベース(CDB および PDB)が正常に起動し、接続できるか確認する。

① CDB(コンテナ DB)へのローカル接続確認:

sqlplus / as sysdba

プロンプトが SQL> に変わったら、以下のコマンドで状態を確認する。

SQL> SELECT name, open_mode FROM v$database;

READ WRITE と表示されていれば正常である。

② PDB(プラガブル DB: FREEPDB1)へのネットワーク接続確認:

手順 4 で設定したパスワードを使用して接続テストを行う。

# 一旦 SQL*Plus を抜けてから以下を実行
sqlplus sys/[手順4で設定したパスワード]@localhost:1521/FREEPDB1 as sysdba

接続に成功すれば、導入はすべて完了となる。必要に応じてアプリケーションからの接続設定等を進めよう。


【データベース内部構造】SQLはどう処理される?クエリ実行の内部プロセスと最適化の流れ

SQL文を発行した際、データベース(RDBMS)内部ではどのような処理が行われているのだろうか。
SQLは「どのようなデータを取得・更新したいか」という宣言的な記述を行う言語であり、「具体的にどのようにデータを取得するか」という手順はRDBMS内部の処理エンジンが自動的に判断している。

今回は、SQLが投入されてから結果が返されるまでの内部ステップと、効率的な実行処理を行うための「クエリ最適化(Query Optimization)」の流れを整理した。


1. SQL処理の5つのステップ

一般的なRDBMSにおいて、SQL文は主に以下の5つの段階を経て実行される。

  • ① Parsing(構文解析)
    送られてきたSQLの文法的な正しさ(シンタックスチェック)を解釈・検証する。
    SQL実行後の最初のプロセスとして、Parser(構文解析器)がSQLのロジカルな構造を関係演算を表す「Query Tree(クエリツリー)」へ変換する。
  • ② Query Validation(クエリ検証・意味解析)
    SQL内に指定されたテーブルや列(カラム)がデータベース上に実際に存在するか、アクセス権限があるかなどの「意味的妥当性」を検証する。
  • ③ Optimization(最適化 / クエリ最適化)
    関係演算を表す Query Tree を、実際のアクセス手順である「物理的な実行プラン(Execution Plan)」へ変換する。
    通常、データ取得の手順には複数のバリエーション(多くのプラン)が存在するため、その中で最も効率が良い(低コストな)実行プランを選択する。
  • ④ Plan Compile(プランコンパイル)
    クエリオプティマイザ(Query Optimizer)によって選択された最適な計画を、実行エンジンが直接処理できるマシンコードや内部コマンド形式へコンパイル・変換する。
  • ⑤ Execution(実行)
    Query 実行エンジン(Execution Engine)が物理プランに従ってストレージやキャッシュメモリからデータを読み書きし、最終的な結果をクライアントへ返す。

2. クエリ最適化(Query Optimization)の役割

SQLの処理工程の中で、パフォーマンスを決定づける最も重要なコンポーネントが「クエリオプティマイザ(Query Optimizer)」である。

【クエリ最適化の仕組みとポイント】

■ 物理プランの大量生成
1つのSQLに対して、「フルスキャンをするか / インデックスを使うか」「テーブル結合の順序をどうするか」「ハッシュ結合かループ結合か」など、多数の物理プラン候補が生成される。

■ コスト評価(Cost-Based Optimization)
オプティマイザは統計情報(データ件数、インデックスのカーディナリティ、データ配置など)を参照し、推定実行時間やI/Oコストなどの「いろいろな値」から最適なプランを算出・算出決定する。

■ 実行エンジンへの受け渡し
最小コストと判定された計画(最適プラン)のみが選択され、Query 実行エンジンに渡されて高速な処理が実現される。

3. まとめ

SQLは「データ取得の結果」を指示するだけで、裏側ではParser(構文解析器)による Query Tree の生成と、Query Optimizer(最適化エンジン)による物理実行プランの決定という高度な処理が自動的に行われている。

SQLパフォーマンスチューニングにおいては、オプティマイザが意図通りの最適な実行プランを選択できるよう、「最新の統計情報(Statistics)の維持」や「適切なインデックス設計」を行うことが重要となる。

【SQL実行プロセスから見るチューニングのポイント】
✔ プレースホルダ(バインド変数)を使い、Parsing・Plan Compileの再利用(ハードパース削減)を狙えているか?
✔ テーブル統計情報は最新に更新されているか?(古い統計情報だとオプティマイザが間違ったプランを選ぶ)
✔ EXPLAIN / AUTOTRACE 等で最適化された物理実行プランを分析しているか?

【データベース】分散システムの限界を示す!CAP定理(CAP Theorem)とは

分散データベースやNoSQLの選定・設計において、避けて通れない非常に重要な理論が「CAP定理(CAP Theorem)」である。
(※一般に「CPA」ではなく「CAP」と呼ばれることが多い概念だ)

CAP定理とは、「分散システムにおいて『一貫性』『可用性』『分断耐性』の3つの性質を、同時にすべて(3つとも)満たすことはできない」というトレードオフの定理を指す。


1. CAP定理の3つの構成要素

分散システムが備えるべき3つの評価軸の定義は以下の通りである。

  • C:Consistency(一貫性)
    システムにあるオペレーションを行った後、どのノード(サーバー)にアクセスしても常に最新で同じデータ(一貫性)が保たれている性質。
    分散システムで一貫性を担保するためには、あるノードでデータ更新(Update)が発生した場合、他のすべてのノードにもその結果を即座に同期・反映しなければならない。
  • A:Availability(可用性)
    システムを構成するノードの一部が故障(ダウン)しても、システム全体としてはレスポンスを返し続け、正常に稼働し続けなければならない性質。
    エラーを返さず、常にすべての正常なノードが読み書きの要求に応答できることが求められる。
  • P:Partition Tolerance(分断耐性)
    ノード間を結ぶネットワークが障害等で分断され、通信が一時的に不通・切断されても、システムとしては停止せずに稼働し続けなければならない性質。

2. なぜ3つ同時に満たせないのか?

ネットワーク分断(P)が発生した状況を想像してみよう。ノードAとノードBの間で通信ができない状態である。

このとき、ノードAに書き込みリクエストが届いた場合、選択肢は2つしかない。

  • 選択肢①:一貫性(C)を優先する ➔ ノードBへデータ更新を同期できないため、エラーを返して書き込みを拒否する。(可用性 A が犠牲になる)
  • 選択肢②:可用性(A)を優先する ➔ ノードAだけで書き込みを完了させ、応答を返す。しかしノードBのデータは古いままになる。(一貫性 C が犠牲になる)

このように、現実の分散環境において「分断(P)」の発生を完全に回避することは不可能なため、実質的に分散システムは「CP型」か「AP型」のどちらかを選択(トレードオフ)せざるを得ないのである。


3. NoSQLにおけるCAPによる分類

近代のNoSQLデータベースは、この3つのうち「どれを重視し、どれを妥協するか」という設計思想(トレードオフ)によって、大きく3つのタイプに分類することができる。

【CAP特性によるデータベース分類】

■ CP型(一貫性 + 分断耐性)
・特徴:ネットワーク分断時はエラーを返してでもデータ不整合を防ぐ。
・代表例:HBase, MongoDB, Redis, Accumulo
・用途:金融決済や在庫管理など、絶対的なデータ整合性が求められるシステム。

■ AP型(可用性 + 分断耐性)
・特徴:データ整合性が一時的に崩れても、止まらずに読み書きに応答する(※結果的一貫性を重視)。
・代表例:Apache Cassandra, Amazon DynamoDB, CouchDB
・用途:SNSのタイムラインやアクセスログの収集など、止まらないことが最優先のシステム。

■ CA型(一貫性 + 可用性)
・特徴:ネットワーク分断が発生しない単一ノード(非分散環境)を前提とするモデル。
・代表例:従来の単一構成RDBMS(PostgreSQL, MySQL, Oracle DB など)
・注意:分散環境においてはネットワーク障害(P)の回避が困難なため、実質の選択肢としては「CP」か「AP」の2択となる。

4. まとめ

「すべての面で完璧なデータベース」は存在しない。システム要件に応じて、「一貫性(C)」を絶対に譲れないのか、あるいは「高可用性(A)」を取って一時的な不整合(Eventual Consistency:結果的一貫性)を許容するのかを見極めることが、適切なDB選定の第一歩となる。

【CAP定理から考えるデータベース選定の要点】
✔ 金融・決済・アカウント管理など、1円・1件のズレも許されない ➔ CP型(または伝統的RDBMS)
✔ ログ収集・SNS・カートの一時保持など、止まらないことが最優先 ➔ AP型
✔ AP型を採用する場合は「結果的一貫性(最終的にデータが合えばOK)」の思想を許容できるか確認する