2025年12月28日 星期日

9. PDB 資源管理

在 Multitenant 架構下,一個 CDB 底下可能會建立多個 PDB ,若多個 PDB 同時執行不同的工作負載時,

有可能在 PDB 之間會造成系統資源的爭用,此時可藉由管控 PDB 的資源使用量來避免這個情況,總共有

兩種方式,一個於 CDB 層級建立 CDB Resource Plan 、 另一個是直接於每一個 PDB 限制其資源的使用。

 

  • CDB Resource Plan

CDB Resource Plan 主要針對 PDB 的 CPU 使用量以及 Parallel Execution 的資源做一個限制, 

CDB Resource Plan 主要設定三個參數, Share 、 utilization_limit 以及 parallel_server_limit ,例如設定

一個 Plan 如下 :

PDB

shares 

utilization_limit 

parallel_server_limit 

PDB1

3

100

100

PDB2

2

70

70

Default

1

50

50


Shares 表示當 PDB 發生資源爭用時,確保此 PDB 能使用到多少資源, Shares 的加總為 6 ,因此 PDB1 

確保能使用到 3/6 的資源 、 PDB2 能使用到 2/6 的資源,其餘沒有指定的 PDB 則套用 Default 1/6 的資源

; utilization_limit 限制在套用此 Plan 下 PDB 最多能使用多少 % 的 CPU Resource , PDB1 100% 表示沒

有限制 、 PDB2 即使在資源沒有爭用的時候最多只能使用 70% CPU ,其餘 Default 則是只能使用 50% ;

 parallel_server_limit 限制 PDB 最多能使用多少 % 的 parallel server ,同理 PDB1 沒有限制 、 PDB2 能使

用 70% 的 parallel server , Default 則是 50% 。


使用 DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN 來建立 CDB Resource Plan 、 

DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE 來分配資源給 PDB :

建立 CDB Resource Plan :

SQL> exec DBMS_RESOURCE_MANAGER.clear_pending_area;

SQL> exec DBMS_RESOURCE_MANAGER.create_pending_area;

SQL> begin

     DBMS_RESOURCE_MANAGER.create_cdb_plan(plan => 'cdb_plan',comment => 'New CDB Plan');

     end;

     /

建立 PDB1 的 Plan Directive :

SQL> begin

      DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE(

      plan => 'cdb_plan',

      pluggable_database => 'PDB1',

      shares => 3,

      utilization_limit => 100,

      parallel_server_limit => 100);

     end;

     /

建立 PDB2 的 Plan Directive :

SQL> begin

      DBMS_RESOURCE_MANAGER.CREATE_CDB_PLAN_DIRECTIVE(

      plan => 'cdb_plan',

      pluggable_database => 'PDB2',

      shares => 2,

      utilization_limit => 70,

      parallel_server_limit => 70);

     end;

     /

設定 Default 的 Plan Directive :

SQL> begin

      DBMS_RESOURCE_MANAGER.UPDATE_CDB_DEFAULT_DIRECTIVE(

      plan => 'cdb_plan',

      new_shares => 1,

      new_utilization_limit => 50,

      new_parallel_server_limit => 50);

     end;

     /

Submit Plan :

SQL> exec DBMS_RESOURCE_MANAGER.validate_pending_area;

SQL> exec DBMS_RESOURCE_MANAGER.submit_pending_area;


於 CDB 設定 resource_manager_plan 進行套用 :

SQL> alter system set resource_manager_plan='cdb_plan';


透過 dba_cdb_rsrc_plans 可查詢目前所有的 Resource Plan , dba_cdb_rsrc_plan_directives 可查詢 

Resource Plan 的相關設定 :

SQL> select plan_id, plan, comments, status, mandatory 

      from dba_cdb_rsrc_plans;


SQL> column plan format a30

     column pluggable_database format a25

     column profile format a25

select plan, pluggable_database, profile, shares, utilization_limit util, parallel_server_limit parallel 

from dba_cdb_rsrc_plan_directives

where plan = 'CDB_PLAN';


如果要進行更新則使用 DBMS_RESOURCE_MANAGER.UPDATE_CDB_PLAN_DIRECTIVE ,

例如將 PDB1 的 utilization_limit 設定為 90 :

SQL> begin

     DBMS_RESOURCE_MANAGER.clear_pending_area;

     DBMS_RESOURCE_MANAGER.create_pending_area;

     DBMS_RESOURCE_MANAGER.UPDATE_CDB_PLAN_DIRECTIVE(

      plan => 'cdb_plan',

      pluggable_database => 'PDB1',

      new_utilization_limit => 90);

     DBMS_RESOURCE_MANAGER.validate_pending_area;

     DBMS_RESOURCE_MANAGER.submit_pending_area;

   end;

/      


刪除 Plan 則是使用 DBMS_RESOURCE_MANAGER.delete_cdb_plan 刪除整個 Plan 或是 

DBMS_RESOURCE_MANAGER.delete_cdb_plan_directive 刪除某一筆設定 :

SQL> alter system set resource_manager_plan='';

SQL> begin

      DBMS_RESOURCE_MANAGER.clear_pending_area;

      DBMS_RESOURCE_MANAGER.create_pending_area;

      DBMS_RESOURCE_MANAGER.delete_cdb_plan (plan=>'CDB_PLAN');

      DBMS_RESOURCE_MANAGER.validate_pending_area;

      DBMS_RESOURCE_MANAGER.submit_pending_area;

     end;

     /


除了直接設定 PDB 的 Directive ,另外也可以透過 profile 的方式來設定,例如設定 profile 如下 :

Profile

shares 

utilization_limit 

parallel_server_limit 

high

3

90

90

low

1

50

50


使用 DBMS_RESOURCE_MANAGER.create_cdb_profile_directive 進行設定 :

SQL> alter system set resource_manager_plan='';

SQL> begin

      DBMS_RESOURCE_MANAGER.clear_pending_area;

      DBMS_RESOURCE_MANAGER.create_pending_area;

      DBMS_RESOURCE_MANAGER.create_cdb_profile_directive(

      plan => 'cdb_plan',

      profile => 'high',

      shares => 3,

      utilization_limit => 90,

      parallel_server_limit => 90);

      DBMS_RESOURCE_MANAGER.create_cdb_profile_directive(

      plan => 'cdb_plan',

      profile => 'low',

      shares => 1,

      utilization_limit => 50,

      parallel_server_limit => 50);

      DBMS_RESOURCE_MANAGER.validate_pending_area;

      DBMS_RESOURCE_MANAGER.submit_pending_area;

     end;

     /


設定好之後於個別 PDB 設定參數 db_performance_profile 進行套用 :

CDB 設定 PLAN :

SQL> alter system set resource_manager_plan='CDB_PLAN';

PDB 進行套用 :

SQL> alter session set container=pdb1;

SQL> alter system set db_performance_profile='HIGH';

SQL> alter session set container=pdb2;

SQL> alter system set db_performance_profile='LOW';


同理對於 profile 的變更、刪除可以使用 DBMS_RESOURCE_MANAGER.update_cdb_profile_directive 

與 DBMS_RESOURCE_MANAGER.delete_cdb_profile_directive 。


在套用完 CDB Resource Plan 之後,可以於 CDB 層級查詢 dba_hist_rsrc_pdb_metric 來檢視 PDB 資源

的使用情況。


  • PDB Resource Limit

針對單一個 PDB 的 Resource 限制可以從 CPU 、 Memory 與 IO 三個面向進行設定。


設定參數 cpu_count 可以用來限制單一個 PDB 能使用多少 CPU Resource ,如果同時有 CDB Resource 

Plan 設定的 utilization_limit 與 PDB 內部設定的 cpu_count ,則會取兩者的最小值作為限制。


PDB 的 memory 限制主要是設定 SGA 與 PGA , PDB 的 sga_target / sga_max_size 設定單一個 PDB 最

多能夠使用多少 SGA ,但設定不能超過 CDB 層級的 sga_target ,除此之外 PDB 還能夠設定 sga_min_size 

保證這個 PDB 最少能夠使用多少 SGA ,但 sga_min_size 設定不能超過 PDB sga_target 的 50% ,所有 

PDB 加總的 sga_min_size 不能超過 CDB sga_target 的 50% ; db_cache_size 與 shared_pool_size 用來設

定單一 PDB 的最小 buffer cache 與 shared pool ,同樣單一個 PDB 的 db_cache_size 與 shared_pool_size 

設定不能超過 CDB db_cache_size 的 50% 以及 CDB shared_pool_size 的 50% ,所有 PDB 的 db_cache_size 

與 shared_pool_size 加總不能超過 CDB sga_target 的 50% ; PDB 的 pga_aggregate_target 用來設定單一 

PDB 的 PGA 使用率,同樣設定不能超過 CDB pga_aggregate_target 的 50% , PDB 的 pga_aggregate_limit 

設定則是不能超過 CDB 的 pga_aggregate_limit 。


PDB 的 I/O 限制可以透過兩個參數 max_iops 與 max_mbps 進行設定, max_iops 設定單一 PDB 每秒最大的 

IOPS 、 max_mbps 設定單一 PDB 每秒最大的 IO megabytes ,查詢 DBA_HIST_RSRC_PDB_METRIC 可以

檢視 PDB 的資源使用情況,作為設定 max_iops 與 max_mbps 的依據,這邊要注意的是,若是限制了 PDB 的

 I/O ,當 I/O 使用量超過了限制,則會產生 rsmgr:io rate limit 的等待事件。


Multitenant 架構下的資源管理比起傳統 Non-CDB 的資料管理較為複雜, DBA 需要注意分配給 PDB 的資源是

否足夠,避免產生效能問題。

2025年11月25日 星期二

8. Pluggable Database 備份與還原

  • Backup

Pluggable Database 備份的方式與傳統的 Non-CDB 備份方式無異,不同的是 Multitenant 架構下

有分為 CDB 的備份與 PDB 的備份,一般情況下於 CDB 層級執行 backup database 會將 CDB 以及

底下的所有 PDB 一起備份,例如於 CDB 執行 full backup ,包含 CDB$ROOT 以及全部的 PDB 都會

一起備份 :

$ rman target /

RMAN> 

run {

crosscheck backup;

crosscheck archivelog all;

allocate channel ch1 type disk;

allocate channel ch2 type disk;

delete noprompt obsolete;

backup database format '/u02/backup/fulldb_%s_%t';

sql 'alter system archive log current';

backup archivelog all format '/u02/backup/archivelog_%t_%s_%p' delete input;

backup current controlfile format '/u02/backup/controlfile_%s_%t';

backup spfile format '/u02/backup/spfile_%T_%U';

release channel ch1;

release channel ch2;

}


 如果只要備份 PDB 可以使用 backup pluggable database 單獨備份 PDB :

備份 Pluggable database PDB1 :

RMAN> backup pluggable database pdb1 format '/u02/backup/pdb1_%s_%t';

備份 CDB$ROOT 與 PDB1 :

RMAN> backup pluggable database "CDB$ROOT",PDB1 format '/u02/backup/pdb1_%s_%t';


由於 PDB 必須要有外層的 CDB 才能夠存在,因此備份的時候比較不會只單獨備份 PDB ,

至少會備份 CDB$ROOT 加上所需要的 PDB ,這樣還原的時候才不會因為沒有 CDB$ROOT 

造成 PDB 無法還原。


如果是需要 Duplicate 整個 CDB ,可以使用 skip pluggable database 排除某些 PDB 不要進行 duplicate ,

不一定整個 CDB 底下的所有 PDB 都進行 duplicate :

Duplicate CDB 排除 PDB_ROOT,PDB_APP1,PDB_APP2 :

$ rman target /

RMAN> connect auxiliary sys/welcome1@cdb2

run {

 allocate auxiliary channel ch1 type disk;

 allocate auxiliary channel ch2 type disk;

 duplicate database to cdb2;

 skip pluggable database PDB_ROOT,PDB_APP1,PDB_APP2;

 nofilenamecheck;

 }


  • Restore

Restore 整個 CDB 的方式與原本還原 Non-CDB 的方式無異。如果只是將 PDB restore 至原本的 CDB 

只需要簡單的執行 restore pluggable database 就可以了 :

還原 PDB2 至原本的 CDB :

$ sqlplus / as sysdba

SQL> alter pluggable database pdb2 close abort;

$ rman target /

RMAN> restore pluggable database pdb2;

RMAN> recover pluggable database pdb2;

RMAN> exit;

$ sqlplus / as sysdba

SQL> alter pluggable database pdb2 open;


這邊要注意的是,如果執行了 drop pluggable database 命令之後,就沒有辦法簡單的使用 restore 來還原了,

例如執行了 drop pluggable database PDB2 將 PDB2 drop ,此時就無法直接 restore 了,因為執行了 drop 

命令之後,這個 PDB 的 metadata 已不存在 CDB ,此時如果再執行 restore pluggable database 便會出現 

RMAN-06813: could not translate pluggable database PDB2 錯誤 :

A screen shot of a computer screen

AI-generated content may be incorrect.


這個時候只能使用 PDB PITR (Point In Time Recovery) 來進行還原,它的原理是利用備份先還原到 

auxiliary destination ,然後再將 PDB unplug / plug 回來,例如使用 PITR 來還原 PDB2 :

還原 PDB2 至原本的 CDB :

$ rman target /

RMAN> run {

set until time "to_timestamp('20251124 16:40:00','yyyymmdd hh24:mi:ss')";

recover pluggable database pdb2 auxiliary destination='/u02/auxiliary';

alter pluggable database pdb2 open resetlogs;

}


這邊要注意的是,設定 until time 的時間必須要有 CDB$ROOT 與 PDB2 的備份,並且 auxiliary destination 

的空間必須要可以容納 CDB$ROOT + PDB2 才行。


  • Flashback

最後來說一下 flashback database , PDB 可以單獨執行 flashback database ,只要於 CDB 層級有

 enable flashback database 功能即可,首先於 CDB 層級啟用 flashback :

SQL> show con_name

CON_NAME

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

CDB$ROOT


SQL> alter system set db_recovery_file_dest_size=30G;

SQL> alter system set db_recovery_file_dest='/u01/recovery_area';

SQL> SQL> alter database flashback on;


例如於 PDB2 建立 restore point 以及單獨進行 flashback :

建立 restore point :

SQL> alter session set container=pdb2;

SQL> create restore point rp_2025 guarantee flashback database;

執行 flashback database :

SQL> alter session set container=pdb2;

SQL> alter pluggable database close immediate;

SQL> flashback pluggable database to restore point rp_2025;

SQL> alter pluggable database open resetlogs;


總結 Multitenant 的備份與傳統的 Non-CDB 備份差異不大, DBA 只需要注意 PDB 必須連同其所在的 

CDB$ROOT 一起備份即可。