1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ORACLE_PDB_SIDの使用上の注意点

1
Last updated at Posted at 2026-06-11

はじめに

環境変数ORACLE_PDB_SIDを使用すると、OS認証でSQL*Plusから直接PDBに接続できます。
この環境変数を使用する場合には注意点があります。

  1. ORACLE_PDB_SIDで直接PDBに接続できるのは、SYS, SYSTEMユーザーのみ
  2. rmanのOS認証を利用した接続もORACLE_PDB_SIDの動作対象になる
  3. 存在しないPDB名をORACLE_PDB_SIDに設定すると、CDB$ROOTに接続される
  4. ORACLE_PDB_SIDを設定したままSQL*Plusでデータベースを起動後に、SYS, SYSTEMユーザでNet*Service接続するとPDBに接続される

特に注意したいのは、4つ目の「ORACLE_PDB_SIDを設定したままSQL*Plusでデータベースを起動後に、SYS, SYSTEMユーザでNet*Service接続するとPDBに接続される」点です。
以下、Oracle Database 19cで検証した結果をもとに記載しています。

ORACLE_PDB_SIDの動作の仕組み

ORACLE_PDB_SIDで指定したPDBに接続される動作は、CDB$ROOTに定義されているログオントリガー DBMS_SET_PDBによるものです。
DBMS_SET_PDBはOracle標準のSYS所有のログオントリガーです。
ログオン処理で一度CDB$ROOTに接続 → DBMS_SET_PDBトリガーでセッションのカレントコンテナを変更(alter session set container)という動作になります。

SQL> set pagesize 50000
SQL> set linesize 100
SQL> set long 1048576
SQL> set longchunksize 1048576
SQL> select dbms_metadata.get_ddl('TRIGGER', 'DBMS_SET_PDB', 'SYS') from dual;

DBMS_METADATA.GET_DDL('TRIGGER','DBMS_SET_PDB','SYS')
----------------------------------------------------------------------------------------------------

  CREATE OR REPLACE NONEDITIONABLE TRIGGER "SYS"."DBMS_SET_PDB" after logon on database
        WHEN (user = 'SYS' or user = 'SYSTEM') declare
         pdb_name varchar2(64);
         begin
           DBMS_SYSTEM.get_env ('ORACLE_PDB_SID', pdb_name);
           if(pdb_name is not null)
            then
              EXECUTE IMMEDIATE 'alter session set container = ' || '"' || pdb_name
                    || '"';
            end if;
         exception
           when others then
           NULL;
         end dbms_set_pdb;
ALTER TRIGGER "SYS"."DBMS_SET_PDB" ENABLE

DBMS_SET_PDBトリガーを無効化すると、常にCDB$ROOTに接続されます。

1. ORACLE_PDB_SIDで直接PDBに接続できるのは、SYS, SYSTEMユーザーのみ

DBMS_SET_PDBのDDLを見ると、動作対象はSYS, SYSTEMユーザーであることがわかります。
共通ユーザーc##adminでは、常にCDB$ROOTに接続されることを確認しています。

共通ユーザーの作成

$ sqlplus / as sysdba
SQL> alter session set container = CDB$ROOT;
SQL> create user c##admin identified by admin_password container = all;
SQL> grant create session to c##admin container = all;
SQL> exit

SYSユーザーのローカル接続

$ export ORACLE_PDB_SID=PDB1_1
$ sqlplus -S / as sysdba << EOF
> show con_name
> EOF

CON_NAME
------------------------------
PDB1_1

c##adminユーザーのローカル接続

$ export ORACLE_PDB_SID=PDB1_1
$ sqlplus -S c##admin/admin_password << EOF
> show con_name
> EOF

CON_NAME
------------------------------
CDB$ROOT

2. rmanのOS認証を利用した接続もORACLE_PDB_SIDの動作対象になる

ORACLE_PDB_SIDはSQL*Plusだけでなく、RMANで接続した場合(rman target / や rman target sys/<sys_password>)も動作対象になります。

$ export ORACLE_PDB_SID=PDB1_1
$ rman target /

Recovery Manager: Release 19.0.0.0.0 - Production on Thu Jun 11 08:24:39 2026
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

connected to target database: CDB1:PDB1_1 (DBID=4053075928)

CDB$ROOTに接続した場合は、"connected to target database: CDB1"と出力されます。
今回はPDB1_1に接続されたので、"connected to target database: CDB1:PDB1_1"と出力されています。

3. 存在しないPDB名をORACLE_PDB_SIDに設定すると、CDB$ROOTに接続される

存在しないPDBをORACLE_PDB_SIDに指定してOS認証で接続した場合、alter sessionが失敗するため、CDB$ROOTに接続されます。

$ export ORACLE_PDB_SID=PDB1_2
$ sqlplus -S / as sysdba << EOF
> show con_name
> show pdbs
> EOF

CON_NAME
------------------------------
CDB$ROOT

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDB1_1                         READ WRITE NO

4. ORACLE_PDB_SIDを設定したままSQL*Plusでデータベースを起動後に、SYS, SYSTEMユーザでNet*Service接続するとPDBに接続される

SYSやSYSTEMユーザ限定になりますが、非常に注意する内容です。
Net*Service経由でもPDBに接続されるようになると、接続元(クライアント側)のORACLE_PDB_SIDが設定されていなくてもPDBに接続されるようになります。
DBMS_SET_PDBトリガーを無効にするとCDB$ROOTに接続できるようになることから、このトリガーが原因であることが特定できています。
※ 下記例のcdb1はCDB$ROOTへのデフォルトサービス名です。

$ unset ORACLE_PDB_SID
$ sqlplus -S / as sysdba << EOF
> shutdown immediate
> EOF
$ export ORACLE_PDB_SID=PDB1_1
$ sqlplus -S / as sysdba << EOF
> startup
> EOF
$ unset ORACLE_PDB_SID
$ sqlplus -S sys/sys_password@listener_ip/cdb1 as sysdba << EOF
> show con_name
> EOF

CON_NAME
------------------------------
PDB1_1

rmanでNet*Service経由で接続するとPDBに接続されるため、CDB$ROOTに接続して行う操作が実行できなくなります。

$ unset ORACLE_PDB_SID
$ rman target sys/sys_password@listener_ip/cdb1

Recovery Manager: Release 19.0.0.0.0 - Production on Thu Jun 11 08:34:50 2026
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

connected to target database: CDB1:PDB1_1 (DBID=4053075928)

Clusterware環境での影響

Oracle Restart、RAC One Node、RAC環境において、ORACLE_PDB_SIDを設定した状態で

  • srvctl start database
  • srvctl stop database
  • srvctl relocate database

を実行した場合は、本事象を再現しませんでした(検証済)。

対処法

本事象が発生した場合は、以下のいずれかで解消できます。

  • ORACLE_PDB_SIDを未設定にしてOracle Databaseを再起動する
$ unset ORACLE_PDB_SID
$ sqlplus / as sysdba
SQL> shutdown immediate
SQL> startup
  • DBMS_SET_PDBトリガーを(一時的)に無効化する
$ unset ORACLE_PDB_SID
$ sqlplus / as sysdba
SQL> alter trigger sys.dbms_set_pdb disable;

※ DBMS_SET_PDBはOracle標準トリガーであるため、本番環境では十分な検証を行ったうえで実施してください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?