2025年9月26日 星期五

6. Data Guard on Multitenant Database

Multitenant Database 的 Data Guard 建置方式與傳統 Non-CDB 的建置方式無異,在 Oracle 12c 至 19c 的

版本只能於 CDB 層級來建置 Data Guard ,自 Oracle 21c 之後就可以只在 PDB 層級建置 Data Guard 。


在 CDB 層級建立 Data Guard 之後需要探討的問題是,未來在此 CDB 上建立新的 PDB 是否會同步到 standby 

端 ? 以下分別說明同步與不會同步的兩種情境 :

  • PDB 自動同步至 Standby 的情境

有兩個情境在 Primary 建立新 PDB 時會自動同步到 Standby :

1. Create PDB from seed

於 Primary 使用 seed 建立新的 PDB 時,所有的操作會自動同步到 Standby 端,例如在 Primary 建立 pdb3 

會自動同步到 Standby :

SQL> create pluggable database pdb3 admin user pdbadmin identified by welcome1 file_name_convert=('pdbseed','pdb3');


在 Standby 的 alter log 可以看到新的 PDB3 自動被建立出來 :

A screenshot of a computer program

AI-generated content may be incorrect.

如果這個情境下反而不想同步到 Standby 端,那麼在 create pluggable 的語法當中加上 STANDBYS=NONE 

就不會同步了。


2. Clone PDB from Read-Only PDB

如果是以 clone 的方式建立 PDB ,則來源端 PDB 必須為 Read-Only 才能夠自動同步到 Standby ,

例如 Create PDB4 from Local PDB3 ,此時 PDB4 會自動同步到 Standby :

SQL> alter pluggable database pdb3 close immediate;

SQL> alter pluggable database pdb3 open read only;

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


在 Standby 的 alter log 可以看到新的 PDB4 自動被建立出來 :

A screenshot of a computer program

AI-generated content may be incorrect.


如果是 Clone from Remote PDB 則限制較多,除了要求 Remote PDB 必須為 Read only 之外, 

Standby Database 必須為 ADG 且設定參數 standby_pdb_source_file_dblink 才會自動同步,

例如 Create rpdb from Remote Clone :

Enable ADG on Standby :

SQL> shutdown immediate

SQL> startup mount

SQL> alter database open read only

SQL> alter database recover managed standby database disconnect;

SQL> alter system set standby_pdb_source_file_dblink='rcdb';


Create PDB from Remote on Primary :

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


在這個情境下比較特殊, Standby 實際上是透過 DB Link 直接去 Remote Source PDB 拉 datafile 

而非從 Primary 拉,standby_pdb_source_file_dblink 設定的是連線到 Source Database 的 DB Link 名稱

,而且此 DB Link 必須要能夠連線成功,如果設定都沒錯的話 Standby 就會自動同步建立此 PDB :

A screenshot of a computer program

AI-generated content may be incorrect.


如果此時 Standby 沒有啟用 ADG ,則會因為無法使用 DB Link 來 restore datafile 造成 MRP crash :

A screenshot of a computer program

AI-generated content may be incorrect.

此時必須先將新建的 PDB disable recovery 才能夠重新啟用 MRP :

SQL> alter session set container=rpdb;

SQL> alter pluggable database disable recovery;

SQL> exit;

$ sqlplus / as sysdba

SQL> alter database recover managed standby database disconnect;



  • PDB 不會同步至 Standby 的情境

使用 Clone 的方式建立 PDB 不論是從 Local Clone 或是 Remote Clone ,只要 Source PDB 不是 Read Only 的情況下

,新建的 PDB 就不會自動同步至 Standby ,此時必須手動針對新的 PDB 進行 restore 並且 enable recovery ,

例如 Create wpdb from Read Write pdb :

SQL> create pluggable database wpdb from wpdb@rcdb file_name_convert=('SQLMGMT/wpdb','ORAPDB/wpdb');

SQL> alter pluggable database wpdb open;


此時 Standby 端只會建立 Metadata 不會 restore datafile ,也就是此時 Standby 端只有 wpdb 的空殼而已 :

A screenshot of a computer screen

AI-generated content may be incorrect.

此時必須於 Standby 端進行 restore pluggable database :

$ rman target /

RMAN>  run {

set newname for datafile 112 to '/u01/oradata/ORAPDBS/wpdb/system01.dbf';

set newname for datafile 113 to '/u01/oradata/ORAPDBS/wpdb/sysaux01.dbf';

set newname for datafile 114 to '/u01/oradata/ORAPDBS/wpdb/undotbs01.dbf';

restore pluggable database wpdb from service orapdb;

switch datafile 112 to copy;

switch datafile 113 to copy;

switch datafile 114 to copy;

}


Restore 結束後必須再 enable recovery 才能夠同步 :

$ sqlplus / as sysdba

SQL> alter database recover managed standby database cancel;

SQL> alter session set container=wpdb;

SQL> alter pluggable database enable recovery;

SQL> exit;

$ sqlplus / as sysdba

SQL> alter database recover managed standby database disconnect;


 

除此之外,如果在 Primary 針對 PDB 進行 flashback 的操作, Standby 端也會同步針對這個 PDB 進行 flashback ,

例如於 Primary 端針對 PDB2 進行 flashback ,首先必須於 Standby 端確認 Standby 有啟用 flashback 功能 :

A black screen with white text

AI-generated content may be incorrect.

從 Primary 針對 PDB2 進行 flashback 的操作 :

SQL> alter pluggable database pdb2 close immediate;

SQL> flashback pluggable database pdb2 to restore point rp;

SQL> alter pluggable database pdb2 open resetlogs;


在 pdb2 open resetlogs 的同時可以看到 Standby 端同步進行了 flashback 的動作 :

A screenshot of a computer

AI-generated content may be incorrect.

Data Guard 在有 CDB/PDB 的情況下較為複雜, DBA 在日常維運上必須要非常了解這些情境。



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