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 的位置。



2025年5月30日 星期五

2. 建立與刪除 PDB

建立 PDB 可以使用 DBCA ,執行後選擇 Manage Pluggable database

A screenshot of a computer

Description automatically generated


選擇 Create a Pluggable database

A white background with black text

Description automatically generated


選擇要建立 PDB 的 Container database 

A screenshot of a computer

Description automatically generated


後續步驟依 DBCA 的指示依序執行即可。


除了使用 DBCA ,也可以直接透過 SQL*PLUS 以 Command Line 的方式來建立 PDB 。


  • Create PDB from PDB$SEED :

SQL> create pluggable database pdb2 admin user pdbadmin identified by welcome1 default tablespace users datafile '/u01/oradata/ORAPDB/pdb2/users01.dbf' size 5M file_name_convert=('pdbseed','pdb2');

SQL> alter pluggable database pdb2 open;


如果不指定 file_name_convert 則會依照參數 db_create_file_dest 所設定的位置以 OMF 的格式建立 datafile ,如果沒有設定 db_create_file_dest 則必須指定 file_name_convert ,否則會出現 ORA-65016 錯誤 :

A black screen with white text

Description automatically generated

先設定參數 db_create_file_dest 就無需使用 file_name_convert

SQL> alter session set db_create_file_dest='/u01/oradata';

SQL> create pluggable database pdb3 admin user pdbadmin identified by welcome1 default tablespace users datafile;

SQL> alter pluggable database pdb3 open;


另外也可以使用參數 pdb_file_name_convert ,這樣子在建立過程中也無須使用 file_name_convert ,與 db_create_file_dest 的差別在於 db_create_file_dest 是使用 OMF 格式進行建立,而 pdb_file_name_convert 只是更改 datafile 的路徑位置,檔案名稱還是會依照 PDB$SEED 的格式 :

SQL> alter session set pdb_file_name_convert='pdbseed','pdb4';

SQL> create pluggable database pdb4 admin user pdbadmin identified by welcome1 default tablespace users datafile '/u01/oradata/ORAPDB/pdb4/user01.dbf' size 5M;

SQL> alter pluggable database pdb4 open;


  • Create PDB from PDB Clone :

使用 PDB Clone 的方式建立 PDB 可以從 Local PDB 或者是透過 DB Link 從 Remote PDB 進行 Clone :

From Local :

SQL> create pluggable database pdb5 from pdb4 file_name_convert=('pdb4','pdb5');


From Remote :

SQL> create public database link rcdb connect to c##admin identified by welcome1 using 'rcdb';

SQL> create pluggable database pdb6 from rpdb@rcdb file_name_convert=('rpdb','pdb6');

SQL> alter pluggable database pdb6 open;


這邊要注意的是,建立 db link 是在 CDB 層級並且所使用的 user 必須要有 create pluggable database 的權限,否則會出現錯誤 ORA-17628: Oracle error 1031 returned by remote Oracle server ;另外 Remote PDB 必須 Enable Local Undo 才能進行 Remote Clone ,不過以現在 19c 的版本來說,預設就已經是 Enable Local Undo 了 。

SQL> select property_name, property_value

From database_properties

where  property_name = 'LOCAL_UNDO_ENABLED'


PROPERTY_NAME                      PROPERTY_VALUE

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

LOCAL_UNDO_ENABLED           TRUE


如果 PDB 要設定 TDE 則須先建立 encryption key 再進行 activate :

SQL> alter session set container=pdb6;

SQL> administer key management create encryption key using tag 'pdb6' force keystore identified by welcome1 with backup using 'pdb6';


keystore altered.


SQL> select key_id from v$encryption_keys where tag='pdb6';


KEY_ID

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

ATIrNovtp0/xv0kCwplOgFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


SQL> administer key management use encryption key 'ATIrNovtp0/xv0kCwplOgFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' force keystore identified by welcome1 with backup;


keystore altered.


SQL> select key_id,activation_time,tag from v$encryption_keys;


KEY_ID

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

ACTIVATION_TIME

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

TAG

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

ATIrNovtp0/xv0kCwplOgFoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

30-MAY-25 06.05.52.594777 PM +08:00

pdb6


刪除 PDB 同樣的也可以使用 DBCA 來進行刪除 ,在 Manage Pluggable database 的選項底下選擇 Delete a Pluggable database 即可 :

A screenshot of a computer

Description automatically generated


使用 SQL*PLUS 的話直接執行 drop pluggable database 即可 :

SQL> drop pluggable database pdb3 including datafiles;