天天看點

Thread 1 cannot allocate new log的問題分析

發生oracle當機事故,alert檔案中報告如下錯誤:

Fri Jan 12 04:07:49 2007

Thread 1 cannot allocate new log, sequence 187398

Checkpoint not complete

産生此問題的原因分析:

CKPT這個背景程序的就是做checkpoint這件事,checkpoint被觸發的條件之一是就發生redo log switch,Checkpoint的具體工作包括:

• 觸發DBWn向磁盤寫入Dirty data。

• 把checkpoint資訊更新到datafile header上。

• 把checkpoint資訊更新到control file裡。

Checkpoint做的事情之一是觸發DBWn把buffer cache中的Dirty cache磁盤。另外就是把最近的系統的SCN更新到datafile header和control file(每一個事務都有一個SCN),做第一件事的目的是為了減少由于系統突然當機而需要的恢複時間,做第二件事實為了保證資料庫的一緻性。   而redo log switch就是觸發checkpoint的主要的事件(event) ,當第一組redo log被用完之後,Oracle就要停止使用目前的redo log,轉而使用另一組redo log,這就叫做log switch。而log switch觸發checkpoint。   Oracle要求的最少的redo group 的是2個,但我們一般都建議配置3個或3個以上redo log group。假設我們隻有兩個redo log group:group 1和group 2,并且系統中總是有大量的dirty block需要寫入datafile,當我們從group 1 switch to group 2的時候,會觸發checkpoint, checkpoint要求DBWn把buffer cache中的dirty block寫入datafile,然而,當我們再次用完group 2裡面的空間,需要再次switch to group 1并重用group 1的時候,如果我們發現redo log group 1所保護的那些dirty block還沒有完全寫入到datafile,整個資料庫必須等待DBWn把所有的dirty block寫入到datafile之後才能做其他的事情,這就是我們遇到的“checkpoint not complete”問題。這個問題往往暗示了redo log的配置有問題,就本例而言,要麼是redo log太小,要麼是像我們這裡的redo log group太少,隻有2個。而這個問題的解決方案就是加大redo log或添加更多redo log group,不管哪一種解決方案,我們的目的都是給DBWn争取更多的時間。

參考其它解釋如下:

當系統要重新利用某個日志檔案的時候,系統需要将該日志檔案所 包括的buffer cache 中的dirty block 寫到相應的資料檔案。由于對于一個資料庫操作而言,它可能産生的redo 量僅僅是幾十位元組,但是對于buffer cache中确是一個block (一般為8k)。是以,對于一個僅僅是幾百M的日志檔案,它所保護的buffer cache 可能是幾個G

一旦發生"Thread 1 cannot allocate new log",表明系統的checkpoint 沒有來得及完成,也就是說 buffer cache 中的dirty data還沒有完全寫到資料檔案,就已經有大量的日志需要寫入到系統。而系統隻能通知應用:checkpoint 還沒有完成,你隻能等待。這個時候,系統就基本處于hang 狀态了 When the database waits on checkpoints,redo generation is stopped until the

log switch is done

如果,我們在這個時候檢視系統資訊,就會發現:v$log中的日志狀态大多處于active 狀态; v$session_wait 中會有很多log file switch 事件的發生

解決辦法:

a. 添加更多的日志檔案  

b. 加大checkpoint 觸發的頻度  

c. 減小redo log 的size

d. 提高DBWR的效率

e. 為了更好的了解系統的運作,可以設定

      log_checkpoint_interval = 0 log_checkpoint_timeout = 0 log_checkpoints_to_alert=True

參考資料:

這個主題使DBA能對checkpoint和checkpoint優化的參數有一個較好的了解:

- FAST_START_MTTR_TARGET

- LOG_CHECKPOINT_INTERVAL

- LOG_CHECKPOINT_TIMEOUT

- LOG_CHECKPOINTS_TO_ALERT

它也解釋了怎樣解釋和處理出現在ALERT<sid>.LOG file中的

checkpoint的錯誤"'Checkpoint not Complete' and 'Cannot Allocate New Log"

什麼是checkpoint?

checkpoint是為了記憶體中已經被修改的資料塊與磁盤資料檔案同步的一種資料庫事件。它提供了一種

保持事務送出以後資料一緻的手段。往Oracle磁盤寫髒資料的機制與事務送出不是同步的。

checkpoint有兩個目地:1.確定資料一緻性。2.使資料庫能快速地恢複。怎樣快速恢複呢?

因為資料庫會把所有的改變都在資料檔案上設定checkpoint,并一直增加,它不需要請求checkpoint

之前的重做日志.Checkpoint能保證所有在緩存區的資料寫到相應的資料檔案,防止因為意外的執行個體

失敗導緻的資料丢失。

Oracle寫這個髒資料隻在一定的條件下:

後面的程序需要1/4個db_block_buffer參數的大小

每三秒

當一個checkpoint産生

一個checkpoint有5中事件類型:

每次重做日志的切換

LOG_CHECKPOINT_TIMEOUT 這個延遲參數的到達。

相應位元組(LOG_CHECKPOINT_INTERVAL* size of IO OS blocks)被寫到目前的重做日志

IO OS blocks: 在UNIX下可以 # fstyp -v /dev/vg00/lvol1

vxfs

version: 5

f_bsize: 8192

ALTER SYSTEM SWITCH LOGFILE 這個指令會直接導緻checkpoint發生

ALTER SYSTEM CHECKPOINT

Checkpoint期間會有下面程序發生:

DBWR寫所有髒資料到資料檔案

LGWR更新控制檔案和資料檔案的SCN

Checkpoints和優化

Checkpoints是一個資料庫優化的難點。頻繁的Checkpoints可以實作快速的恢複,但也會使性能

下降。DBA怎樣處理這個問題呢?

依賴于資料庫資料檔案的數量,一個Checkpoint可能是高速的運作。因為所有的資料檔案在Checkpoint

期間都會被當機。更頻繁的Checkpoints可以快速恢複資料庫。這也客戶對不按規定系統當機的容忍的原因。

然而,在一些特殊情況下,頻繁的Checkpoints也不能保證可以快速恢複。我們假設資料庫在95%的時間

内是正常運作,5%由于執行個體失敗導緻不可用,要求恢複。對大多數客戶而言,他們更希望調整95%

的性能而不是5%的當機時間。

這個假設表明,性能是擺在第一位的,是以我門的目标就是在優化期間減少Checkpoints的頻繁度。

優化Checkpoints包括4個關鍵的初始化參數:

詳細介紹每個參數:

FAST_START_MTTR_TARGET

Oracle9i以來FAST_START_MTTR_TARGET 參數是調整checkpoint的首選的方法。

FAST_START_MTTR_TARGET 可以指定單執行個體恢複需要的秒數。基于内部的統計,增長的

checkpoint會自動調整的checkpint的目标以滿足FAST_START_MTTR_TARGET 的需求。

V$INSTANCE_RECOVERY.ESTIMATED_MTTR 顯示目前估計需要恢複的秒數。這個值會被顯示

即使FAST_START_MTTR_TARGET 沒有被指定。

V$INSTANCE_RECOVERY.TARGET_MTTR 表明在短時間内MTTR的目标。

V$MTTR_TARGET_ADVICE 顯示這個目前MTTR設定的工作量産生的I/O數量和其他I/O。

這個視圖幫助使用者評定這個在優化和恢複之前的平衡。

LOG_CHECKPOINT_INTERVAL

LOG_CHECKPOINT_INTERVAL 參數指定這個最大的重做塊的間隔數目。

如果FAST_START_MTTR_TARGET被指定,LOG_CHECKPOINT_INTERVAL不能被設定為0.

在大多數Unix系統的OS塊大小是512位元組。設定LOG_CHECKPOINT_INTERVAL=10000意味着

這個增長的checkpoint不能追加到目前日志因為多于5M。如果你的重做日志是20M,你将

發出4個checkpoint對每個重做日志。

LOG_CHECKPOINT_INTERVAL 會發生影響當一個checkpoint發生時,小心設定這個參數,

保持它随着重做日志檔案大小變化而變化。checkpoint頻繁是這個影響資料庫恢複的原因之一。

短的checkpoint間隔意味資料庫将快速恢複,也增加了資源的利用。

這個參數也影響資料庫向前復原的時間。實際的恢複時間是基于這個時間,當然還有失敗的類型和

需要歸檔日志的數量。

LOG_CHECKPOINT_TIMEOUT

這個參數指定checkpoint發出的時間間隔。換句話說,它指定一次髒資料多少時間寫出一次。

checkpoint頻率會影響這個資料庫恢複的時間。長時間的間隔會要求資料庫恢複要求更久。

Oracle建議用LOG_CHECKPOINT_interval去控制checkpoint而不用LOG_CHECKPOINT_TIMEOUT

,LOG_CHECKPOINT_TIMEOUT每n秒發一次checkpoint,不顧事務送出的頻率。這可能會導緻一些

沒有必要的checkpoint在事務已經變化的情況下。不必要的checkpoint必須被避免。

還有一個容易誤解的地方:LOG_CHECKPOINT_TIMEOUT 會間隔性地發出log switch。

而Log switch會觸發一個checkpoint,但checkpoint不會導緻一個log switch.唯一手工方式

alter system switch logfile或者重新設定redo logs大小 可以導緻頻繁switch.

線上重做日志的大小是關鍵的對于優化和恢複。

解決方法:

If redo logs switch every 3 minutes, you will see performance degradation.

This indicates the redo logs are not sized large enough to efficiently handle

the transaction load.

Statspack snapshots can be taken every 15 minutes or so, these reports gather useful

information about number of checkpoints started and checkpoints completed and number

of database buffers written during checkpointing for that window of time . It also contains

statistics about redo activity. Gathering and comparing these snapshot reports gives you

a complete idea about checkpointing performance at different periods of time.