2026年2月27日 星期五

Log File Sync 事件分析

在 Oracle 資料庫進行 commit 的行為就會產生 log file sync 事件,對於一個交易型的系統來說,理解 log file sync 是非常重要的一件事, log file sync 等待時間的長短往往直接決定了交易型系統的整體效能。

log file sync 等待事件指的是 commit 從開始到結束整個過程,流程大致如下 :


user session 執行 commit 指令,此時會通知 LGWR 將 redo buffer 的信息寫入 redo log , LGWR 接收到通知後,開始進行 I/O 寫入的動作,完成後告知 user session 完成整個 commit 的流程。

log file sync 一定會伴隨著 log file parallel write 事件,也就是中間 LGWR 進行 I/O 寫入的過程,當發生 log file sync 的效能問題時,必須與 log file parallel write 等待事件一起分析,因為有可能是 I/O 效能不佳進而增加整個 log file sync 等待時間。

一般 log file sync 等待時間過長有幾種可能 :

  • redo log 切換太頻繁

Redo Log 切換太頻繁往往是影響 log file sync 等待時間的主因,頻繁的 commit 或 rollback ,或是 redo log 的大小與數量不合適都有可能造成 redo log 切換太頻繁。

  • LGWR 的 I/O 性能不佳

I/O 性能不佳也是造成 log file sync 事件拉長的原因之一, LGWR 寫入的速度來不及處理頻繁的 commit 行為,也就是 log file parallel write 的時間過長。

從 AWR Report 看到 log file sync 等待事件時,可以從幾個方向開始分析 :


首先必須檢查資料庫的 alert log ,先確認是否有 redo log 切換太頻繁的問題,如果 alert log 有顯示出大量的 Checkpoint not complete 訊息,那就表示 redo log 因為來不及切換導致等待事件發生 :

如果有這種現象,那就表示 redo log 數量不足,或者是 redo log 大小不合適,那麼只需調整 redo log 數量與大小即可。

若是沒有這個現象,那就表示沒有 redo log 切換太頻繁的問題,此時就很有可能是 I/O 效能的問題,可以檢查 AWR 的 Background Wait Events 是否 log file parallel write 的等待時間過長,或者是從 lgwr 的 trace file 檢查 LGWR 的寫入速度 :

以這個例子來說, LGWR 只有寫入幾 KB 或是幾十 KB 就需要十幾秒甚或至百秒,那就可以確定 I/O 的效能有問題,此時就必須請系統管理員協助處理 I/O 效能的問題。

當發生 log file sync 效能問題時,除了檢查 alert log 、 lgwr trace 之外, DB 層面還可以收集 ASH (dba_hist_active_sess_history 、 wrh$_active_session_history) 資訊 ,作業系統層面可以收集監控資訊如 OSWatcher 、 NMON …等,更進一步可以執行 strace(Linux) 、 truss(AIX) 例如 :

# strace -rfttT -o /tmp/start_trace.out -p <PID_of_ LGWR process>

透過 strace 可掌握 I/O 行為實際停滯的 system call ,對於深入分析 log file parallel write 等待事件的效能根因具有相當大的幫助。

 

總結 log file sync 等待事件對交易型系統(OLTP)的效能影響相當重大。建議將 redo log 放置於效能較佳、延遲較低的磁碟設備上;同時在應用程式設計上,對交易行為盡量採用批次處理,降低 commit 的發生頻率。透過這些做法,有助於有效縮短 log file sync 的等待時間,進而提升整體交易效能與系統吞吐量。

 

2026年1月29日 星期四

10. PDB Lockdown Profile

PDB lockdown profile 主要是用來限制 PDB 的某些操作,當一個使用者在多個 PDB 共用時

(例如 common user) ,使用者的權限就有被放大的風險,透過設定 PDB lockdown profile 可

以用來避免 common user 利用特定 PDB 所允許的功能進而對其它 PDB 造成影響。


PDB lockdown profile 可以限制三個層級 :

  • Statement : 限制命令的操作,例如於 CDB 層級建立 PDB lockdown profile 限制 alter system 操作 :

SQL> create lockdown profile lkp1;

SQL> alter lockdown profile lkp1 disable statement=('alter system');


於 PDB 設定參數 pdb_lockdown 套用 lockdown profile :

SQL> alter session set container=pdb1;

SQL> alter system set pdb_lockdown=lkp1;


套用之後此 PDB 就不能使用 alter system 命令 :

A black screen with white text

AI-generated content may be incorrect.

更進一步的設定可以只限制某個 alter system 操作,例如只限制 set 操作 :

SQL> alter lockdown profile lkp1 enable statement=('alter system');

SQL> alter lockdown profile lkp1 disable statement=('alter system') clause=('set');


這樣子設定可以執行 alter system 但 set 操作則是不允許 :

A black screen with white text

AI-generated content may be incorrect.

  • Feature : 限制 PDB 使用某些功能如 NETWORK_ACCESS (UTL_HTTP 、 UTL_TCP …等) 、 

    COMMON_SCHEMA_ACCESS (存取 common schema 共用物件) 、 OS_ACCESS (UTL_FILE …等) 、 

    JAVA與 JAVA_RUNTIME ,例如限制 PDB 不能使用 UTL_HTTP :

SQL> create lockdown profile lkp2;

SQL> alter lockdown profile lkp2 disable feature=('UTL_HTTP');


套用之後 PDB 使用 UTL_HTTP 就會出現 ORA-01031: insufficient privileges :

SQL> alter session set container=pdb1;

SQL> alter system set pdb_lockdown=lkp2;

A screen shot of a computer

AI-generated content may be incorrect.

  • Option : 限制 PDB 不能使用某些資料庫功能如 Partitioning 、 Advanced Queuing 、 

    Data Guard …等,例如限制 PDB 不能使用 Partition :

SQL> create lockdown profile lkp3;

SQL> alter lockdown profile lkp3 disable option=('PARTITIONING');

 

 套用之後於 PDB 建立 partition table 就會出現 ORA-00439: feature not enabled :

SQL> alter session set container=pdb1;

SQL> alter system set pdb_lockdown=lkp3;

A screen shot of a computer code

AI-generated content may be incorrect.

透過 dba_lockdown_profiles 可以查詢目前所有 lockdown profile 的設定 :

SQL> select PROFILE_NAME,RULE_TYPE,RULE,status from dba_lockdown_profiles;

A screen shot of a computer

AI-generated content may be incorrect.


PDB Lockdown Profile 提供了一種以 PDB 為邊界的安全控管機制,可有效限制系統操作、

功能與授權選項的使用範圍。

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 的資源是

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