常見的Checkpoint not complete問題分析解決

lygle發表於2013-03-28

首先我們來看下 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做的事情之一是觸發DBWnbuffer cache中的Dirty cache磁碟。另外就是把最近的系統的SCN更新到datafile headercontrol 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能對checkpointcheckpoint優化的引數有一個較好的理解:

- FAST_START_MTTR_TARGET
- LOG_CHECKPOINT_INTERVAL

- LOG_CHECKPOINT_TIMEOUT
- LOG_CHECKPOINTS_TO_ALERT

它也解釋了怎樣解釋和處理出現在ALERT.LOG file中的checkpoint的錯誤"'Checkpoint not Complete' and 'Cannot Allocate New Log"

什麼是checkpoint

Checkpoint是為了記憶體中已經被修改的資料塊與磁碟資料檔案同步的一種資料庫事件。它提供了一種保持事務提交以後資料一致的手段。往Oracle磁碟寫髒資料的機制與事務提交不是同步的。

checkpoint有兩個目的:

1、確保資料一致性。

2、使資料庫能快速地恢復。

怎樣快速恢復

因為資料庫會把所有的改變都在資料檔案上設定checkpoint並一直增加,它不需要請求checkpoint之前的重做日誌,Checkpoint能保證所有在快取區的資料寫到相應的資料檔案,防止因為意外的例項失敗導致的資料丟失。

Oracle寫這個髒資料只在一定的條件下:
1DBWR 超時,大約3秒時間
2系統中沒有多的空緩衝區來存放資料
3CKPT程式(產生新的checkpoint) 觸發DBWR

一個checkpoint5中事件型別:
1、每次重做日誌的切換;
2LOG_CHECKPOINT_TIMEOUT 這個延遲引數的到達;
3、相應位元組(LOG_CHECKPOINT_INTERVAL* size of IO OS blocks)被寫到當前的重做日誌;
4ALTER SYSTEM SWITCH LOGFILE 這個命令會直接導致checkpoint發生
5ALTER 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,你將發出4checkpoint對每個重做日誌。


LOG_CHECKPOINT_INTERVAL 會發生影響當一個checkpoint發生時,小心設定這個引數,保持它隨著重做日誌檔案大小變化而變化。checkpoint頻繁是這個影響資料庫恢復的原因之一。短的checkpoint間隔意味資料庫將快速恢復,也增加了資源的利用。這個引數也影響資料庫向前回滾的時間。實際的恢復時間是基於這個時間,當然還有失敗的型別和需要歸檔日誌的數量。

LOG_CHECKPOINT_TIMEOUT
這個引數指定checkpoint發出的時間間隔。換句話說,它指定一次髒資料多少時間寫出一次。checkpoint頻率會影響這個資料庫恢復的時間。長時間的間隔會要求資料庫恢復要求更久。Oracle建議用LOG_CHECKPOINT_interval去控制checkpoint而不用LOG_CHECKPOINT_TIMEOUTLOG_CHECKPOINT_TIMEOUTn秒發一次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

因為56 我們還沒有用,所以顯示為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分鐘切換一次

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28673746/viewspace-757367/,如需轉載,請註明出處,否則將追究法律責任。

相關文章