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

【Oracle Database 26ai / 接続設計】マルチテナント環境における SQL*Plus 接続手法の全貌と環境変数(ORACLE_SID・TWO_TASK・ORACLE_PDB_SID)の正しい使い分け

Oracle 11g などの従来型アーキテクチャから、Oracle 26ai(マルチテナント・アーキテクチャ)へ移行する際に多くのエンジニアが戸惑うポイントが「データベースへの接続手法と環境変数の挙動」である。

マルチテナント環境では、大元である親領域(CDB)と、個別のデータが格納される子領域(PDB)の関係性を踏まえ、用途に応じた適切な接続経路を選ぶ必要がある。今回は、SQL*Plus を用いた接続の基本原則から、4つの接続手法、そして制御に関わる環境変数の違いまで詳しく解説する。


1. マルチテナント環境における接続の基本原則

Oracle 26ai におけるインスタンス構造と接続の仕組みには、いくつかの重要な前提がある。

  • OSから見える実体は CDB のみ: メモリ構造(SGA)やバックグラウンドプロセスを所有するのは CDB インスタンスである。PDB は CDB のメモリ空間上で論理的に動作する領域のため、OS レベルで PDB 単体を認識する独立したプロセスは存在しない。
  • ORACLE_SID は CDB 専用: 環境変数 ORACLE_SID に指定できるのは常に CDB 名(例: ora26ai)のみである。PDB 名を直接指定して OS ローカル接続を行うことはできない。
  • デフォルトの着地点は CDB$ROOT: OS 認証(sqlplus / as sysdba)で接続した場合、カレントコンテナは必ず最上位の親領域である CDB$ROOT になる。

2. CDB(CDB$ROOT)への接続手順

CDB 全体の管理作業(PDB の作成・削除、インスタンス全体のパラメータ変更など)を行う場合は、CDB(CDB$ROOT)へ直接接続する。

# 1. CDB の SID を環境変数に設定
export ORACLE_SID=ora26ai

# 2. OS 認証で SYSDBA 接続
sqlplus / as sysdba

接続状態の確認用 SQL:

-- 現在のコンテナ名を確認(CDB$ROOT と表示されます)
SHOW CON_NAME;

-- データベース全体(CDB)の名前を確認
SELECT name, cdb FROM v$database;

3. PDB(HR 等)への接続手法(4つのアプローチ)

個別の PDB(アプリケーションデータや移行データが格納される領域)へ接続するには、主に以下の4つの手法が存在する。作業内容や運用スタイルに応じて使い分けよう。

手法①:CDB 接続後のコンテナ切り替え(DBA 作業向け)

OS 認証でいったん CDB$ROOT に着地した後、SQL*Plus 内でセッションのコンテナを移動する最も標準的なDBA向け手法。

export ORACLE_SID=ora26ai
sqlplus / as sysdba

SQL> ALTER SESSION SET CONTAINER = HR;
SQL> SHOW CON_NAME; -- 'HR' と表示されれば完了

手法②:サービス名(TNS)を指定したネットワーク接続(推奨)

リスナー経由で PDB に割り振られた「サービス名」を指定して直接接続する。一般ユーザーやアプリケーションからの接続における標準的な手法。

# 1. 簡易接続ネーミング(Easy Connect)による接続
sqlplus system/Password123#@localhost:1521/HR

# 2. SYSDBA 権限で PDB に直接入る場合
sqlplus sys/Password123#@localhost:1521/HR as sysdba

手法③:環境変数 TWO_TASK による自動接続リダイレクト

Linux/UNIX 環境において TWO_TASK(Windows の場合は LOCAL)を設定すると、sqlplus 実行時に暗黙的に指定した TNS / サービス名経由の接続へリダイレクトされる。

export ORACLE_SID=ora26ai
export TWO_TASK=HR
# 引数なしのログインで、自動的に localhost:1521/HR 経由の接続になる
sqlplus system/Password123#

手法④:環境変数 ORACLE_PDB_SID による自動コンテナ切り替え

Oracle 19c 以降で導入された便利な機能。OS ローカル接続(SYSDBA)の利便性を保ちつつ、ログイン時に自動で目的の PDB へセッションを切り替えることができる。

export ORACLE_SID=ora26ai
export ORACLE_PDB_SID=HR
# OS 認証で接続(内部的に ALTER SESSION SET CONTAINER = HR が自動実行される)
sqlplus / as sysdba

4. 接続制御に関わる環境変数一覧

環境変数名適用レベル設定値の例役割と動作概要
ORACLE_SID OS / インスタンス ora26ai 【必須】接続対象の CDB インスタンス名(メモリ/プロセス)を特定する。
TWO_TASK
(Windows: LOCAL)
SQL*Plus 接続 HR 指定した PDB サービス名(リスナー経由)への暗黙的接続を行う。
ORACLE_PDB_SID SQL*Plus 接続 HR sqlplus / as sysdba 実行時、ログイン直後に該当 PDB へコンテナを自動切替する。
TNS_ADMIN ネットワーク /u01/app/.../admin tnsnames.ora や sqlnet.ora が配置されているディレクトリパスを指定する。

5. 移行運用における推奨構成方針

旧環境(11g等)から Oracle 26ai への移行検証・構築作業を行う際は、環境変数の運用ポリシーをあらかじめ決めておくとミスを防ぐことができる。

  • DBA による構築・検証作業: 基本方針として export ORACLE_SID=ora26ai のみを使用する。インスタンス起動や全体設定時はデフォルトの CDB$ROOT で作業を行い、移行データの確認等で PDB を操作する場合は ALTER SESSION SET CONTAINER = HR; を明示的に呼び出す運用が最も安全で確実。
  • スクリプト・バッチ処理の自動化: アプリケーションやデータ移行バッチ処理(impdp 等)を実行する際は、環境変数に依存せず localhost:1521/HR のようにサービス名を明示的に指定した接続文字列を使用することで、意図しないコンテナへの誤接続を完全に防止する。
まとめ
Oracle 26ai のマルチテナント環境では、「OS上のインスタンス(CDB)の指定」と「論理的な領域(PDB)の選択」を混同しないことが鉄則である。それぞれの接続経路の特徴を正しく理解し、安全で効率的なデータベース運用を実現しよう。
PR

【Oracle Database 26ai / 運用管理】安全かつ確実に行う!Oracle Database 26ai のシャットダウン手順とモード別の違い

データベースの運用管理において、起動と同じくらい重要なのが「正しいシャットダウン手順」の把握である。

マルチテナント・アーキテクチャを採用している Oracle Database 26ai では、コンテナデータベース(CDB)とプラガブルデータベース(PDB)の関係性を理解しておく必要がある。

今回は、日常運用で基本となるCDB全体の安全なシャットダウン手順と、コマンドの違い、さらにPDB単体を個別に停止する手順について詳しく解説する。


1. シャットダウンの基本動作(CDBとPDBの関係)

Oracle 26ai(Free版など)では、親である管理領域 CDB$ROOT に接続して停止コマンドを1つ実行するだけで、配下の子DB(FREEPDB1など)も含めて自動的に安全にクローズ・停止される。

わざわざ子DBを1つずつ個別に停止しにいく必要はないため、基本は親のシャットダウン手順をマスターしておけばOKだ。


2. 全体停止(CDBのシャットダウン)手順

データベース全体を安全に停止する具体的な手順を確認していこう。

Step 1: OS環境変数の設定(起動時と同様)

作業を行うユーザー(通常は oracle ユーザー)でターミナルを開き、環境変数を正しく設定する。

# oracleユーザーに切り替え
su - oracle

# 環境変数の設定(※環境に合わせてパスを確認してください)
export ORACLE_SID=FREE
export ORACLE_HOME=/opt/oracle/product/26c/dbhomeFree

Step 2: CDB$ROOTへの接続とシャットダウン実行

最高管理者権限(SYSDBA)で SQL*Plus に接続し、日常運用で最も安全で確実な SHUTDOWN IMMEDIATE を実行する。

# 1. SYSDBA(最高権限)で接続
sqlplus / as sysdba

# 2. シャットダウンの実行
SQL> SHUTDOWN IMMEDIATE;

【期待される出力結果】:

データベースがクローズされました。
データベースがアンマウントされました。
ORACLEインスタンスがシャットダウンされました。

この処理の裏で、PDB(FREEPDB1)の安全なクローズも自動的に行われるため、これで全体の停止作業は完了となる。


3. 【知識】なぜ「IMMEDIATE」をつけるのか?(シャットダウンモードの比較)

Oracleのシャットダウンにはいくつかのモードが存在する。運用における特徴を把握しておこう。

モード名特徴・挙動実務での扱い
SHUTDOWN IMMEDIATE 実行中のSQLをキャンセルし、未確定データをロールバックして安全に停止する。 ★ 基本・推奨
SHUTDOWN (NORMAL) 全ユーザーが自発的にログアウトするまで永遠に待機するモード。 実務ではほぼ使用しない
SHUTDOWN ABORT OSの電源を強制的に切るような強制終了。 緊急時・障害時のみ

4. 【補足】PDB(FREEPDB1)「だけ」を停止したい場合

「親DB(CDB)全体は稼働させたまま、メンテナンスのために子DB(FREEPDB1)だけを一時的に止めたい」という場合は、以下の専用コマンドを実行する。

-- 1. 現在のPDBの状態を確認(OPENになっていることを確認)
SQL> SHOW PDBS;

-- 2. FREEPDB1 だけをクローズ(停止)する
SQL> ALTER PLUGGABLE DATABASE FREEPDB1 CLOSE IMMEDIATE;

-- 3. 停止後の状態確認
SQL> SHOW PDBS;
まとめ
✔ 通常の停止は CDB$ROOT に接続して SHUTDOWN IMMEDIATE; を実行するだけで、子DBも自動で安全に停止する。
✔ 部分的なメンテナンスでは ALTER PLUGGABLE DATABASE CLOSE IMMEDIATE; を活用して柔軟に管理できる。

【データベース設計の基礎】データ品質を守る「制約」の基本!列制約と表制約の種類・違いをわかりやすく解説

データベースを設計する上で欠かせないのが「制約(Constraint)」である。
制約とは、データベースに不適切なデータが勝手に入り込まないようにするための「番人」のような役割を持つルールだ。

今回は、データベースの基本概念である「列制約」と「表制約」の分類や、それぞれの種類について整理して見ていこう。


1. 対象による分類(列制約と表制約)

データベースの制約は、その適用範囲(対象)によって大きく2つに分類される。

分類概要・特徴
(1)列制約 1つの列(カラム)に対して定義する制約。
(例:ある特定の列にNULLを許可しないなど)
(2)表制約 複数の列の組み合わせ、または表全体に対して定義する制約。
(例:複数列の組み合わせで一意性を担保するなど)

2. 制約の具体的な種類

それぞれの分類に含まれる具体的な制約の種類を確認していこう。

(1)主な列制約

  • ① NOT NULL制約
    対象の列において、値が空(NULL)であることを禁止する制約。必ず何らかのデータが入力されている状態を強制する。
  • ② 一意制約(ユニーク制約)
    列の中で、すでに登録されている値と重複するデータ(同一の値)の入力を禁止する制約。
    ※なお、「複数の列の組」で一意性を定義する場合は、列制約ではなく後述の表制約として定義することになる。
  • ③ CHECK制約
    データの値に対して、特定の条件(「1〜100までの値のみ許可」「特定コードのみ許可」など)を定義し、条件を満たさないデータの登録を防ぐ制約。

(2)主な表制約

  • ① 参照整合性制約(外部キー制約)
    2つの表(テーブル)の間でデータの整合性を保つための制約。
    例えば「親子関係」のテーブル構造において、子テーブルにデータを登録する際、親テーブルに必ず対応する親データが存在することを強制する(「子だけに存在して親がいない」状態を防ぐ)。

3. まとめ

制約の分類代表的な種類主な目的
列制約 NOT NULL、一意制約、CHECK制約 1つの列単位でデータの品質や入力漏れを防ぐ
表制約 複合一意制約、参照整合性制約(外部キー)など 複数列の組み合わせや、テーブル間のデータの整合性を守る

データベースの設計や基本情報技術者試験などの資格試験でも、この「列制約と表制約の違い」「各制約の役割」は定番の重要ポイントである。しっかりと整理して押さえておこう!


【Oracle Cloud / 運用管理】Always Free Autonomous Databaseは放置してて大丈夫?自動停止・自動削除のルールと賢い付き合い方

PL/SQL学習用に構築した OCI の Autonomous AI Database Serverless(Always Free)。

「このまま稼働させっぱなしにしていて料金は発生しないのか?」
「使わないときは手動で停止すべきなのか?」

そんな疑問や不安を持つ方に向けて、Always Free インスタンスの裏側の仕組みと、正しい運用ルールを分かりやすく解説する。


1. 結論:稼働させっぱなしでOK、ただし「放置しすぎ」には注意

結論から言うと、Always Free枠のリソースであるため、起動しっぱなしにしても課金は一切発生しない。 毎回手動で停止・開始を繰り返す必要はなく、使いたいときにいつでもブラウザからアクセスして問題ない。

ただし、Oracleのクラウド環境にはリソース最適化のため、以下の自動管理ルールが設けられている。

状態何が起きるか
7日間連続で操作がない データベースサービスが自動的に停止(STOPPED)する
停止状態が3ヶ月連続で続く データベースが自動的に削除(TERMINATED)される

つまり、「稼働中のまま放置すること」は何の問題もないが、「一切触らずに長期間放置すること」はデータの消滅リスクにつながるため注意が必要である。


2. なぜこういう仕組みになっているのか?

Always Freeは無期限で無料提供される非常に太っ腹な仕組みだが、ユーザーが無制限に放置インスタンスを作り続けると、Oracle側のサーバーリソースを圧迫してしまう。

そのため、「実際に利用されているアクティブなリソースかどうか」を基準に、長期間使われていないものは自動でスリープ・片付けを行うことで、全体のインフラバランスを保っているという背景がある。


3. 手動での「停止」と「再開」を試してみよう

自動停止の挙動を体感しておくために、一度コンソールから手動で停止・再開の操作を試してみるのがおすすめだ。

手動停止の手順

  • 1. OCIコンソールにログインし、対象のAutonomous AI Database Serverlessインスタンスの詳細画面を開く。
  • 2. 画面上部の 「その他アクション」 メニューをクリック。
  • 3. メニューの中から 「停止」 を選択。
  • 4. 確認ダイアログが表示されるので、内容を確認して停止を実行。ステータスが 停止処理中 ➔ 停止済み に変われば完了。

インスタンスを再開する場合

同じ詳細画面の 「その他アクション」 メニューから 「開始」 を選択し、ステータスが 開始処理中 ➔ 使用可能 に戻れば再開完了となる。

停止中に Database Actions へアクセスするとどうなる?
データベースが停止状態のときにブラウザからアクセスを試みると、接続エラーになる。この挙動を知っておくことで、「あ、7日間放置して自動停止したな」と慌てずに対処できるようになる。

4. 実務・学習における運用ルール

学習用途や検証用途で Always Free データベースを安全に維持するためのポイントは以下の通り。

  • 継続的に学習を進める場合: 週に1回以上、Database Actionsにログインして簡単なSQLを実行していれば、7日間の自動停止ルールはクリアできる。
  • しばらく触らない期間ができそうな場合: 忘れずに手動で意図的に「停止」させておくか、OCIコンソールの Events / Notifications 機能で非アクティブ警告を受け取れるように設定しておくと安心。

5. まとめ

利用状況・状態必要な対応・ルール
日常的に使っている(稼働中) 何もしなくてOK。料金の心配も不要。
7日以上操作していない 自動的に停止されるため、使う前に手動で「開始」する。
数週間〜数ヶ月使わない予定 3ヶ月放置すると削除されるため、通知設定をするか定期的にログインする。
手動で止めたい場合 コンソールの「その他アクション」メニューから「停止」「開始」を切替可能。

ルールさえ理解していれば、Always Free はクラウドで手軽にデータベースを学ぶための最強のパートナーである。ルールを味方につけて、安心してPL/SQLの学習を進めていこう!


【PL/SQL入門 第2回】変数を宣言して、値を出力してみよう!DECLAREブロックの書き方と代入演算子(:=)の基本

前回の「Hello World」では、PL/SQLの基本的なブロック構造(BEGIN 〜 END)と画面出力の方法を確認した。

第2回目となる今回は、プログラムの基本であり核心のひとつでもある「変数」の扱い方を解説する。

変数が使えるようになると、動的な値の保持や計算結果の使い回しができるようになり、PL/SQLの表現力が劇的に広がる。Database ActionsのSQLワークシートを開いて、実際に手を動かしながら学んでいこう!


【前提条件】

  • 前回の記事でAutonomous AI Database Serverless環境が構築済みであること。
  • Database Actionsの「SQL」ワークシートが使える状態であること。

1. 変数とは何か(DECLAREブロックの役割)

変数とは、一言でいえば値を一時的に入れておく「箱」のようなものである。PL/SQLでは、処理の途中で計算した値や、データベースから取得したデータを変数に格納し、後続の処理で使い回すことができる。

PL/SQLで変数を使うには、処理を実行するBEGINの前にDECLAREブロックを置く必要がある。前回の「Hello World」はいきなりBEGINから始まっていたが、変数を使う場合は次のような構造になる。

DECLARE
    -- ここで変数を宣言する
BEGIN
    -- ここで実際の処理を書く
END;
/

DECLAREは「宣言する」という英単語のとおり、「これからこのプログラム内で使う変数はこれです」とあらかじめコンパイラに名乗っておくための宣言部である。


2. 変数を宣言して、初期化するサンプル

さっそく、変数を宣言しながら初期値(代入)を行うサンプルコードを実行してみよう。

DECLARE
    -- 変数の宣言と初期化
    v_message  VARCHAR2(20) := 'Hello World';
BEGIN
    -- 変数の出力
    DBMS_OUTPUT.PUT_LINE(v_message);
END;
/

実行結果(想定):

Hello World

PL/SQLプロシージャが正常に完了しました。

経過時間: 00:00:00.006

構文のポイント解説

構文要素意味・解説
v_message 変数名。自分がわかりやすい任意の名前を付けられる。
VARCHAR2(20) データ型。「最大20文字までの可変長文字列」を格納するという定義。
:= 代入演算子。「右辺の値を左辺の変数に入れる」という意味。
'Hello World' 代入する値(文字列リテラルはシングルクォートで囲む)。

Oracle PL/SQLでは、通常の比較で使う = ではなく、:= を使って値を代入するのが特徴である。これはSQL文のWHERE句などにおける条件比較(例:WHERE id = 1)の = と区別するためであり、初心者が最初につまずきやすいポイントなのでしっかり覚えておこう。

命名のちょっとしたルール(プレフィックス)
変数名の先頭に v_ を付けているのは、Oracle PL/SQL開発現場でよく使われる命名慣習(variable の頭文字)である。必須ではないが、「これは変数だ」とひと目でわかるようにしておくことで、コードが長大・複雑になったときの可読性が大きく向上する。

3. 「宣言」と「代入」を分けて書くパターン

先ほどの例は、宣言と同時に値を入れる「初期化」の形だった。これを「宣言」と「代入」を別々の行に分けて書くことももちろん可能である。

DECLARE
    v_message  VARCHAR2(20);  -- 宣言のみ(この時点では中身は空=NULL)
BEGIN
    v_message := 'Hello World';  -- 後から値を代入
    DBMS_OUTPUT.PUT_LINE(v_message);
END;
/

実行結果は先ほどと同じ「Hello World」になるが、プログラムの内部的な処理の流れとしては、

  1. v_message という名前の「空の箱」をメモリ上に用意する(宣言)
  2. その箱に 'Hello World' という文字列を流し込む(代入)
  3. 箱の中身を DBMS_OUTPUT.PUT_LINE で画面に出力する

という3つのステップに分かれている。普段何気なく使う「初期化」という言葉は、実は「宣言」と「代入」を同時に行う省略形なのだということが、この書き方をするとよく理解できる。


4. まとめ

習得項目ポイント・構文
DECLAREブロック 変数を使うときに BEGIN の手前に配置する宣言部
変数の宣言 変数名 データ型;
変数の初期化 変数名 データ型 := 値;
代入演算子 := (比較用の = とは異なるので注意)
変数の出力 DBMS_OUTPUT.PUT_LINE(変数名);

今回はPL/SQLにおける変数の基本と、DECLAREブロックの書き方をマスターした。

次回の予告
変数が使えるようになったら、次は条件によって処理を分岐させる制御構文を学ぼう。
次回は「IF文」による条件分岐の基本と書き方を詳しく解説する予定だ。お楽しみに!