Oracle 性能之 Enq: CF - contention


 

Oracle 性能之 Enq: CF - contention

1 原因

只要是需要讀控制文件的操作期間,都調用並持有 CF enqueue, CF 塊用於控制文件相關事務的序列化 操作和在控制文件共享部分的讀寫操作。

一般來說,控制文件的CF enqueue 鎖的申請和持有時間是非常短暫的。

數據庫的下列操作會調用該鎖:

  • checkpointing
  • switching logfiles
  • archiving redologs
  • performing crash recovery
  • logfile manipulation
  • begin/end hot backup
  • DML access for NOLOGGING objects

2 解決問題

 

2.1 針對持有鎖進程類型處理

 

2.1.1 查看持有鎖會話的進程類型

  • 查找持有鎖的會話:

    select l.sid, p.program, p.pid, p.spid, s.username, s.terminal, s.module, s.action, s.event, s.wait_time, s.seconds_in_wait, s.state
    from v$lock l, v$session s, v$process p
    where l.sid = s.sid
    and s.paddr = p.addr
    and l.type='CF'
    and l.lmode >= 5;
    
  • 查找申請鎖的會話:

    select l.sid, p.program, p.pid, p.spid, s.username, s.terminal, s.module, s.action, s.event, s.wait_time, s.seconds_in_wait, s.state
    from v$lock l, v$session s, v$process p
    where l.sid = s.sid
    and s.paddr = p.addr
    and l.type='CF'
    and l.request >= 5;
    

2.1.2 根據進程類型采取不同的處理方法

  1. 后台進程

如果通過上面的SQL,發現持有鎖的進程是后台進程,比如CKPT,LGWR,ARCn,等,並且已經持有相當 長一段時間,正常來說持有鎖的時間是忽略不計的。 針對這種情況,檢查redo 日志的切換頻率,是不是過快,Oracle 推薦在30分鍾左右切換一次。 查看方法如下:

SELECT
TO_CHAR(FIRST_TIME,'YYYY-MM-DD') DAY,
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'00',1,0)),'99') "00",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'01',1,0)),'99') "01",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'02',1,0)),'99') "02",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'03',1,0)),'99') "03",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'04',1,0)),'99') "04",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'05',1,0)),'99') "05",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'06',1,0)),'99') "06",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'07',1,0)),'99') "07",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'08',1,0)),'99') "08",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'09',1,0)),'99') "09",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'10',1,0)),'99') "10",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'11',1,0)),'99') "11",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'12',1,0)),'99') "12",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'13',1,0)),'99') "13",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'14',1,0)),'99') "14",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'15',1,0)),'99') "15",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'16',1,0)),'99') "16",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'17',1,0)),'99') "17",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'18',1,0)),'99') "18",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'19',1,0)),'99') "19",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'20',1,0)),'99') "20",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'21',1,0)),'99') "21",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'22',1,0)),'99') "22",
TO_CHAR(SUM(DECODE(TO_CHAR(FIRST_TIME,'HH24'),'23',1,0)),'99') "23"
FROM
V$LOG_HISTORY
GROUP BY
TO_CHAR(FIRST_TIME,'YYYY-MM-DD')
ORDER BY 1 DESC;

2. 用戶進程

假如是用戶進程,並且持有鎖的會話在不停的變動, 持有鎖的會話的等待事件是“control file parallel write”.

那么,很有可能產生問題的根源是在nologging 對象上的DML操作。

Nologging 或者 unrecoverable 操作時,Oracle 會將執行這個unrecoverable操作時的SCN 記錄進控制文件。

      下列操作都會引起Nologging模式:

    • direct load (SQL*Loader)
    • direct-load INSERT
    • CREATE TABLE … AS SELECT
    • CREATE INDEX
    • ALTER TABLE … MOVE PARTITION
    • ALTER TABLE … SPLIT PARTITION
    • ALTER INDEX … SPLIT PARTITION
    • ALTER INDEX … REBUILD
    • ALTER INDEX … REBUILD PARTITION
    • INSERT, UPDATE, and DELETE on LOBs in NOCACHE NOLOGGING mode stored out of line

那么當進行以上操作時,持有鎖的會話等待事件一般是"control file parallel wirte", 其 他會話此時再申請 CF enqueue, 就會出現"Ene: CF - contention".

這是一種正常的現象.

2.2 檢查歸檔路徑

如果以上都沒有問題,可以再檢查歸檔.保證歸檔路徑可以正常訪問。

3 總結

如果被堵塞,看實際情況是否可以kill 持有CF enqueue的會話。

前台進程持有CF enqueue: 

      如果嚴重影響數據庫運行,考慮Kill掉持有鎖的會話

后台進程持有CF enqueue, 可采取措施有

  • 加大redo日志
  • 合理安排任務執行時間,避免集中處理數據。
(no term)
確保歸檔路徑可以正常訪問

Author: halberd.lee

Created: 2019-06-18 Tue 13:43

Validate

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM