2025年8月28日 星期四

5. 管理 Pluggable Database

  • PDB 的開啟與關閉

PDB 的開啟與關閉使用的是 alter pluggable database 命令,可以於 CDB 或是 PDB 層級進行操作 :

開啟 PDB1 (如為 RAC 則須加上 instances=all 否則其它 node 的 PDB1 不會開啟)

SQL> alter pluggable database pdb1 open instances=all;

開啟全部的 PDB ,只能於 CDB 層級操作

SQL> alter pluggable database all open instances=all;

關閉 PDB1

SQL> alter pluggable database pdb1 close immediate instances=all;

關閉全部的 PDB ,只能於 CDB 層級操作

SQL> alter pluggable database all close immediate instances=all;


在 PDB 層級也可以使用傳統的 startup 與 shutdown 進行操作 :

開啟 PDB1 (只能開啟當前 node 的 PDB1)

SQL> alter session set container=pdb1;

Session altered.

SQL> startup

Pluggable Database opened.

關閉 PDB1 (只能關閉當前 node 的 PDB1)

SQL> alter session set container=pdb1;

Session altered.

SQL> shutdown immediate

Pluggable Database closed.


  • PDB 自動開啟

預設在 CDB 開啟後 PDB 不會自動開啟,可以使用兩種方法讓 PDB 可以在 CDB 開啟後也自動開啟。

  1. 使用 save state

save state 紀錄原本 PDB 的狀態,若原本 PDB 就處於開啟的狀態,那麼下次 CDB 開啟的時候有

save state 的 PDB 也會自動開啟 :

針對 PDB1 save state

SQL> alter pluggable database pdb1 save state;

全部 PDB save state

SQL> alter pluggable database all save state;

取消 PDB1 save state

SQL> alter pluggable database pdb1 discard state;

取消全部 PDB save state

SQL> alter pluggable database all discard state;


透過 dba_pdb_saved_states 可以查詢哪些 PDB 有 save state :

SQL> select con_id,con_name,state from dba_pdb_saved_states;


  1. 建立 PDB Service

如果為 RAC 或是有安裝 Grid Infrastructure 且 CDB 有註冊在 GI ,那麼可以為 PDB 建立 service ,

在 CDB 啟動的時候會連帶 PDB 與 PDB service 一起開啟 :

PDB1 建立 service pdb_s

$ srvctl add service -d orapdb -pdb pdb1 -s pdb_s


  • 管理 PDB 參數

Multitenant 架構下有些參數只能在 CDB 層級變更,有些參數可以在個別的 PDB 進行變更,可以查詢 

v$parameter 的 ISPDB_MODIFIABLE 來確認參數是否可以於 PDB 層級進行變更。於 CDB 層級查詢 

pdb_spfile$ 可以列出 PDB 層級變更的非預設參數,若是參數沒有進行過變更則不會顯示在 pdb_spfile$ :

SQL> select a.name,b.name,value$ from v$pdbs a,pdb_spfile$ b 

      where a.con_uid=b.pdb_uid order by 1;

A screen shot of a computer program

AI-generated content may be incorrect.


另一種方式則是在 PDB 層級產出 pfile ,此時 pfile 所列出的也是只有變更過的參數 :

SQL> alter session set container=pdb1;

Session altered.

SQL> create pfile='/tmp/pdb1.ora' from spfile;

File created.

[oracle@db19c ~]$ cat /tmp/pdb1.ora

*.db_securefile='PREFERRED'


  • PDB AWR Report

PDB 層級可以建立當前 PDB 單獨的 AWR Report ,建立 AWR 時選擇 AWR_PDB :

SQL> alter session set container=pdb1;

SQL> @?/rdbms/admin/awrrpt

A screen shot of a computer

AI-generated content may be incorrect.

這邊要注意的是,必須要將參數 awr_pdb_autoflush_enabled 設定為 TRUE , PDB 才會自動產生 

AWR Snapshot ,否則必須手動建立 AWR Snapshot ,於 CDB 層級設定為 TRUE ,所有的 PDB 

都會生效 :



2025年7月25日 星期五

4. Migrate Non-CDB to PDB

傳統 Non-CDB 的資料庫架構可以轉換為 PDB 架構 :

A drawing of a cylinder

AI-generated content may be incorrect.


轉換的方式可以使用 XML file 或者是 Remote Clone 。


  • 使用 XML file

Non-CDB 可以透過 DBMS_PDB 這個 Package 產生出 XML file ,然後於 CDB 上使用此 XML file 來建立 PDB 來達到 Non-CDB 轉 PDB 的目的。


在使用 DBMS_PDB 之前必須將 Non-CDB 開啟為 Read Only :

Open Non-CDB ORA19c to Read Only Mode :

SQL> shutdown immediate

SQL> startup mount

SQL> alter database open read only;

SQL> select name,open_mode from v$database;

NAME                        OPEN_MODE

--------------------------- ------------------------------

ORA19C                      READ ONLY


執行 DBMS_PDB.DESCRIBE 產出 XML 檔案 :

SQL> begin

      dbms_pdb.describe(

       pdb_descr_file => '/tmp/ora19c.xml');

     end;

     /

PL/SQL procedure successfully completed.


使用此 XML 檔案於 CDB 建立新的 PDB :

SQL> create pluggable database pora19 using '/tmp/ora19c.xml' file_name_convert=('/u01/oradata/ORA19C','/u01/oradata/ORAPDB/pora19');

Pluggable database created.

SQL> show pdbs

CON_ID CON_NAME               OPEN MODE  RESTRICTED

---------- ------------------------------ ------------------- -----------------

         2 PDB$SEED                   READ ONLY  NO

         3 PDB1                           READ WRITE NO

         4 PDB2                           READ WRITE NO

         7 PORA19                    MOUNTED

         8 RPDB                           READ WRITE NO


於新的 PDB 執行 noncdb_to_pdb.sql 更新 PDB 相關的 Data Dictionary 完成轉換 :

SQL> alter session set container=pora19;

SQL> @?/rdbms/admin/noncdb_to_pdb.sql


Open PDB to READ WRITE MODE

SQL> alter pluggable database pora19 open;


如果 PDB 開啟後 RESTRICTED 為 YES ,則需檢查 pdb_plug_in_violations 並修正錯誤才可以算完成轉換。

SQL> select time,name,cause,type,status,message,action from pdb_plug_in_violations;


  • 使用 Remote Clone

Remote Clone 則是透過 DB Link 的方式將 Non-CDB 建立為 PDB 。

首先於 CDB 建立 DB Link 至來源端的 Non-CDB ,來源端用來作為 DB Link 的使用者必須要有 create pluggable database 的權限 :

Grant create pluggable database to user on Source Non-CDB:

SQL> grant create pluggable database to system;


Create database link from CDB to Non-CDB

SQL> create public database link non_cdb_to_pdb connect to system identified by oracle using 'ora19c';


同樣將來源端的 Non-CDB 開啟至 Read Only :

Open Non-CDB ORA19c to Read Only Mode :

SQL> shutdown immediate

SQL> startup mount

SQL> alter database open read only;


於 CDB 透過 DB Link 建立 PDB :

SQL> create pluggable database pora192 from ora19c@non_cdb_to_pdb file_name_convert=('/u01/oradata/ORA19C','/u01/oradata/ORAPDB/pora192');

Pluggable database created.


於新的 PDB 執行 noncdb_to_pdb.sql完成轉換 :

SQL> alter session set container=pora192;

SQL> @?/rdbms/admin/noncdb_to_pdb.sql

SQL> alter pluggable database pora192 open;


  • 使用 Refreshable Clone PDB

另一種 Clone 的方式可以使用 Refreshable Clone PDB ,在 Source Non-CDB 不是 Read Only 下,使用 Refreshable Clone PDB 來同步 Non-CDB 的資料,直到正式將 Non-CDB 轉換為 PDB 為止,此時 Source Non-CDB 必須為 archive log mode 才行。

A diagram of a data transfer

AI-generated content may be incorrect.


直接從 CDB 透過 DB Link 建立 Refreshable PDB :

SQL> create pluggable database pora193 from ora19c@non_cdb_to_pdb file_name_convert=('/u01/oradata/ORA19C','/u01/oradata/ORAPDB/pora193') refresh mode manual;


refresh mode manual 表示手動執行 refresh 動作,查詢 dba_pdbs 可以檢查目前狀態 :


PDB 必須在 mount 狀態下才可以進行 refresh ,使用 alter pluggable database <pdb_name> refresh 來進行 refresh :

SQL> alter pluggable database pora193 refresh;

Pluggable database altered.


在同步過程中可以隨時開啟 PDB 為 Read Only 來檢查資料是否有正確同步,檢查完畢後再將 PDB 回歸 mount 繼續進行同步 :

SQL> alter pluggable database pora193 open read only;

SQL> alter pluggable database pora193 close immediate;

SQL> alter pluggable database pora193 refresh;


除了手動進行 refresh 外,也可以設定自動 refresh 的間隔時間,例如設定每 1 分鐘同步一次 :

SQL> alter pluggable database pora193 refresh mode every 1 minutes;

Pluggable database altered.


到了 Non-CDB 要正式切換為 PDB 時,就可以停止同步並執行 noncdb_to_pdb.sql :

SQL> alter pluggable database pora193 refresh mode none;

Pluggable database altered.

SQL> alter session set container=pora193;

SQL> @?/rdbms/admin/noncdb_to_pdb.sql


當設定 refresh mode 為 none 時,表示已經切斷同步,此時就不可以再恢復到同步狀態。


執行完 noncdb_to_pdb.sql 後將 PDB 開啟至 READ WRITE MODE 完成切轉。

SQL> alter pluggable database pora193 open;


SQL> show pdbs;


CON_ID CON_NAME           OPEN MODE  RESTRICTED

---------- ------------------------------ ------------------ -------------------

         2 PDB$SEED                   READ ONLY   NO

         3 PDB1                           READ WRITE NO

         4 PDB2                           READ WRITE NO

         9 PORA193                  READ WRITE NO



2025年6月27日 星期五

3. unplug and plug PDB

PDB 可以使用 unplug 與 plug 的方式將其移轉至另一個 CDB當中。

A diagram of a computer data storage

AI-generated content may be incorrect.

  • Unplug PDB

PDB 可以 unplug 至 xml file 或者是 archive file ,差別在於 xml file 只有紀錄此 PDB的 metadata ,而 archive file 則包含 datafile , 類似 dbca 的 template 那樣。


使用 unplug into 的命令將 PDB unplug , unplug 為 xml file 使用副檔名 .xml ; unplug 為 archive file 使用副檔名為 .pdb :

Unplug PDB into xml file :

SQL> alter pluggable database rpdb close immediate;

SQL> alter pluggable database rpdb unplug into '/tmp/rpdb.xml';


Unplug PDB into archive file :

SQL> alter pluggable database rpdb2 close immediate;

SQL> alter pluggable database rpdb2 unplug into '/tmp/rpdb2.pdb';


unplug 出來的 xml file 是一個文字檔,裡面紀錄的此 PDB 的 tablespace 資訊與 datafile 位置 ,而 archive file 為 image 檔,不能使用文字模式編輯:

A screen shot of a computer

AI-generated content may be incorrect.

PDB unplug 之後,其資訊仍然會存在原 CDB 上,必須使用 drop pluggable database 的指令進行刪除:

A black screen with red text

AI-generated content may be incorrect.


刪除已 unplug 的 PDB :

SQL> drop pluggable database rpdb keep datafiles; 🡨 unplug 為 xml file 時 datafile 必須保留

SQL> drop pluggable database rpdb2 including datafiles;


這邊要注意的是, xml file 只是一個路徑的參照,原本的 datafile 必須保留直到 plug 到 CDB 之後才可以刪除,而 archive file 則已包含 datafile ,此時原本的 datafile 就可以刪除 。


  • Plug PDB

Plug PDB 至另一個 CDB 前必須先進行相容性檢查,於新的 CDB 使用 DBMS_PDB.CHECK_PLUG_COMPATIBILITY 進行檢查:

SQL> SET SERVEROUTPUT ON

     DECLARE

      compatible BOOLEAN := FALSE;

     BEGIN   

       compatible := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(

         pdb_descr_file => '/tmp/rpdb.xml', 🡨 檢查 .xml 或 .pdb

         pdb_name       => 'rpdb');

       if compatible then

         DBMS_OUTPUT.PUT_LINE('Is pluggable compatible? YES');

       else 

         DBMS_OUTPUT.PUT_LINE('Is pluggable compatible? NO');

       end if;

     END;


如果檢查沒有通過,則需修正 pdb_plug_in_violations 中的錯誤才能進行 plug :

SQL> select time,name,cause,type,status,message,action from pdb_plug_in_violations;


使用 xml file 進行 plug :

使用原本 PDB的 datafile 

SQL> create pluggable database rpdb using '/tmp/rpdb.xml' nocopy;


複製原本 PDB 的 datafile 至新的位置

SQL> create pluggable database rpdb using '/tmp/rpdb.xml' file_name_convert=('/u01/oradata/SQLMGMT/rpdb','/u01/oradata/ORAPDB/rpdb');


SQL> alter pluggable database rpdb open;


使用 archive file 進行 plug :

SQL> create pluggable database rpdb2 using '/tmp/rpdb2.pdb' file_name_convert=('/tmp','/u01/oradata/ORAPDB/rpdb2');

SQL> alter pluggable database rpdb2 open;


file_name_convert 的設定為 archive file 所在的目錄位置轉換至實際要建立 datafile 的位置。