Redo Log 和Checkpoint not complete
?
?
首先我們來看下?alertSID.log?日志:
?
Mon?Nov?30?17:31:54?2009
Thread?1?advanced?to?log?sequence?14214?(LGWR?switch)
??Current?log#?3?seq#?14214?mem#?0:?/u03/oradata/newccs/redo03.log
Mon?Nov?30?17:34:29?2009
Thread?1?advanced?to?log?sequence?14215?(LGWR?switch)
??Current?log#?1?seq#?14215?mem#?0:?/u03/oradata/newccs/redo01.log
Mon?Nov?30?17:35:54?2009
Thread?1?cannot?allocate?new?log,?sequence?14216
Checkpoint?not?complete
??Current?log#?1?seq#?14215?mem#?0:?/u03/oradata/newccs/redo01.log
Mon?Nov?30?17:35:55?2009
Thread?1?advanced?to?log?sequence?14216?(LGWR?switch)
??Current?log#?2?seq#?14216?mem#?0:?/u03/oradata/newccs/redo02.log
Mon?Nov?30?17:40:25?2009
Thread?1?advanced?to?log?sequence?14217?(LGWR?switch)
??Current?log#?3?seq#?14217?mem#?0:?/u03/oradata/newccs/redo03.log
Mon?Nov?30?17:44:22?2009
Thread?1?advanced?to?log?sequence?14218?(LGWR?switch)
??Current?log#?1?seq#?14218?mem#?0:?/u03/oradata/newccs/redo01.log
?
?
我們先來分析下它的原因和后果:
當我們進行redo 切換的時候,會觸發checkpoint 事件。 觸發該事件有5個條件。 下文有說明。 Checkpoint做的事情之一是觸發DBWn把buffer cache中的Dirty cache磁盤。另外就是把最近的系統的SCN更新到datafile header和control file(每一個事務都有一個SCN),做第一件事的目的是為了減少由于系統突然宕機而需要的恢復時間,做第二件事實為了保證數據庫的一致性。
??????
?????? Checkpoint will flush dirty block to datafile, 從而觸發DBWn書寫dirty buffer,等到redo log覆蓋的dirty block全部被寫入datafile后才能使用redo log(循環使用),如果DBWn寫入過慢,LGWR必須等待DBWn完成,則這時會出現“checkpoint not completed!”。 所以當出現checkpoint? not competed的時候,還會伴隨cannot allocate new log的錯誤。
??????
?????? 如果遇到這個問題,可以增加日志組和增大日志文件,當然也可以修改 checkpoint參數使得檢查點變頻繁一些。
?????? 在出現這個錯誤的時候,數據庫是短暫hang住的,等待checkpoint的完成。 在hang住的時候,沒有日志產生。
?
?
Tom 同學對這個問題的解釋如下:
?
the infamous "checkpoint not complete, cannot allocate new log" message.
?
this occurrs when Oracle attempts to reuse a log file but the checkpoint that would flush
the blocks that may have redo in this log file has not yet completed -- we must wait
until that checkpoint completes before we can reuse that file -- thats when this message is printed.? during this time (when we cannot allocate a new log) processing is suspended in the database while the checkpoint is made to complete ASAP.
-- 我們必須等待checkpoint 的完成, 在這個過程中, 數據庫是短暫的hang住的。
?
The major way to relieve this is to have sufficient log to carry you through peak times.? that way, we can complete the? checkpoint while you are not busy.? also make sure your checkpoints happen as fast as they can (eg: enable ASYNC IO or configure >1 DBWR if ansyc IO cannot be used, make sure disks are not contending with other apps and so on)
?
Another way is to make the log files smaller, hence increasing the frequency with which we checkpoint (log checkpoint interval and other init.ora parameters achieve the same effect btw).
?
?
?
這個主題使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、DBWR?超時,大約3秒時間
2、系統中沒有多的空緩沖區來存放數據
3、CKPT進程(產生新的checkpoint)?觸發DBWR。
?
一個checkpoint有5中事件類型:
1、每次重做日志的切換;
2、LOG_CHECKPOINT_TIMEOUT?這個延遲參數的到達;
3、相應字節(LOG_CHECKPOINT_INTERVAL*?size?of?IO?OS?blocks)被寫到當前的重做日志;
4、ALTER?SYSTEM?SWITCH?LOGFILE?這個命令會直接導致checkpoint發生
5、ALTER?SYSTEM?CHECKPOINT
?
Checkpoint期間會有下面進程發生:
1.?DBWR寫所有臟數據到數據文件;
2.?LGWR更新控制文件和數據文件的SCN。
?
Checkpoints和優化:
Checkpoints是一個數據庫優化的難點。頻繁的Checkpoints可以實現快速的恢復,但也會使性能下降。怎樣處理這個問題呢?
依賴于數據庫數據文件的數量,一個Checkpoint可能是高速的運行。因為所有的數據文件在Checkpoint期間都會被凍結。更頻繁的Checkpoints可以快速恢復數據庫。這也客戶對不按規定系統宕機的容忍的原因。然而,在一些特殊情況下,頻繁的Checkpoints也不能保證可以快速恢復。我們假設數據庫在95%的時間內是正常運行,5%由于實例失敗導致不可用,要求恢復。對大多數客戶而言,他們更希望調整95%的性能而不是5%的宕機時間。這個假設表明,性能是擺在第一位的,所以我門的目標就是在優化期間減少Checkpoints的頻繁度。
?
優化Checkpoints包括4個關鍵的初始化參數:
-?FAST_START_MTTR_TARGET
-?LOG_CHECKPOINT_INTERVAL
-?LOG_CHECKPOINT_TIMEOUT
?-?LOG_CHECKPOINTS_TO_ALERT
?
詳細介紹每個參數:
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。
SQL>?alter?system?set?log_checkpoint_timeout=300;[單位是秒]?
?
log_checkpoint_to_alert:
設置為真,可以在告警日志中觀察到增量檢查點的觸發。
SQL>?alter?system?set?log_checkpoints_to_alert=true;?
?
對于優化和恢復,?在線重做日志的大小是關鍵的。
?
修改Redo?log?大小的操作方法:
查看當前日志組狀態:
SQL>?select?group#,sequence#,bytes,members,status?from?v$log;
?
????GROUP#??SEQUENCE#??BYTES????MEMBERS?STATUS
????----------?----------????----------????----------?----------------
?????????1??????14230???52428800??????????1????ACTIVE
?????????2??????14231???52428800??????????1????CURRENT
?????????3??????14229???52428800??????????1????INACTIVE
?
CURRENT:?表示是當前的日志。
INACTIVE:臟數據已經寫入數據塊。該狀態可以drop。
ACTIVE:?臟數據還沒有寫入數據塊。
?
查看當前日志組成員:
SQL>?select?member?from?v$logfile;
?
MEMBER
--------------------------------------------------------------------------------
/u03/oradata/newccs/redo03.log
/u03/oradata/newccs/redo02.log
/u03/oradata/newccs/redo01.log
?
?
添加online?redo?log組:
SQL>?alter?database?add?logfile?group?4?('/u03/oradata/newccs/redo04.log')?size?100m?reuse;
SQL>?alter?database?add?logfile?group?5?('/u03/oradata/newccs/redo05.log')?size?100m?reuse;
SQL>?alter?database?add?logfile?group?6?('/u03/oradata/newccs/redo06.log')?size?100m?reuse;
?
?
切換歸檔日志:
SQL>?alter?system?switch?logfile;
?
?
查看歸檔文件的狀態,因為只有Inactive的我們才可以drop,它的數據塊已經寫入了數據塊。如果是Active狀態,表示這里的臟數據還沒有寫入寫入數據庫,手工加個全局檢查點,督促CKPT馬上喚醒DBWR寫入臟數據
SQL>alter?system?checkpoint;
SQL>?select?group#,sequence#,bytes,members,status?from?v$log;
????GROUP#??SEQUENCE#??BYTES????MEMBERS?STATUS
????----------?----------????----------????----------?----------------
?????????1??????14230???52428800??????????1????ACTIVE
?????????2??????14231???52428800??????????1????ACTIVE
?????????3??????14229???52428800??????????1????INACTIVE
? ?4??????14229???52428800??????????1????CURRENT
?5??????14229???52428800??????????1????UNUSED
? ?6??????14229???52428800??????????1????UNUSED
?
因為5,6?我們還沒有用,所以顯示為UNUSED
?
刪除redo?log組:
SQL>?alter?database?drop?logfile?group?1;
Database?altered.
或者:
SQL>?alter?database?drop?logfile?'/u03/oradata/newccs/redo01.log';
?
在添加redo?log?group?1.?
SQL>?alter?database?add?logfile?group?1?('/u03/oradata/newccs/redo01.log')?size?100m?reuse;
?
通過刪除在添加,達到對redo?log?group?的resize.?
?
注意兩點
1.?單純加redo?log?group單個文件的大小沒有作用,同一個group里,文件大小都是一致的。
2.?如果是歸檔模式的話,確保已經自動歸檔,如果手動歸檔的話,需要在alter?system?switch?logfile鎖死的時候,用alter?system?log?current?來手動歸檔。或者通過alter?system?archive?log?start打開自動歸檔。否則的話,當redo?log?group切換完整個groups的時候,會一直等待狀態(******).?
?
3. 《Oracle DBA必備技能詳解》(Robert G.Freeman),上面建議redo log 最好是15分鐘切換一次
?
轉載于:https://www.cnblogs.com/Hiberniane/archive/2009/11/30/2488772.html
總結
以上是生活随笔為你收集整理的Redo Log 和Checkpoint not complete的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU-3460 Ancient Pri
- 下一篇: HTML5小例子