oracle檢查點的相關知識

xz43發表於2010-12-07

一、檢查點概述
大多數關係型資料庫都採用"在提交時並不強迫針對資料塊的修改完成"而是"提交時保證修改記錄(以重做日誌的形式)寫入日誌檔案"的機制,來獲得效能的優勢。這句話的另外一種描述是:當使用者提交事務,寫資料檔案是"非同步"的,寫日誌檔案是"同步"的。這就可能導致資料庫例項崩潰時,記憶體中的DB_Buffer 中的修改過的資料,可能沒有寫入到資料塊中。資料庫在重新開啟時,需要進行恢復,來恢復DB Buffer 中的資料狀態,並確保已經提交的資料被寫入到資料塊中。檢查點是這個過程中的重要機制,透過它來確定,恢復時哪些重做日誌應該被掃描並應用於恢復。
要了解這個檢查點,首先要知道checkpoint queu概念,檢查點發生後,觸發dbwn,CKPT獲取發生檢查點時對應的SCN,通知DBWn要寫到這個SCN為止,
dbwr 寫dirty buffer 是根據 buffer 在被首次 modify的時候的時間的順序寫出,也就是 buffer被modify 的時候會進入一個queue (checkpoint queue),dbwr 就根據queue從其中批次地寫到資料檔案。由於這裡有一個順序的關係,所以 dbwr的寫的進度就是可衡量的,寫到哪個buffer的時候該buffer的首次變化時候的scn就是當前所有資料檔案block的最新scn,但是由於無法適時的將dbwr的進度記錄下來,所以oracle 選擇了一些策略。 其中就包括ckpt程式的檢查點和心跳。
檢查點發生以後,CKPT程式檢查checkpoint queue(也就是髒塊連結串列)是否過長,如果是,則觸發DBWn,將一部分髒塊寫入資料檔案,從而縮短checkpoint queue。

checkpoint 發生時,一方面通知dbwr進行下一批寫操作,(dbwr 寫入的時候,一次寫的塊數是有一個批次寫的隱藏引數控制的。)另一方面,oracle 採用了一個心跳的概念,以3秒的頻率將dbwr 寫的進度反映到控制檔案中,也就是把dbwr當前剛寫完的dirty buffer對應的scn 寫入資料檔案頭和控制檔案,這就是檢查點scn。
這個3秒和增量檢查點不是一個概念,3秒只是在控制檔案中,ckpt 程式去更新當前 dbwr寫到哪裡了,這個對於 ckpt 程式來說叫 heartbeat ,heartbeat是3秒一次,3秒可以看作不停的檢查並記錄檢查點執行情況(DBWR的寫進度)。
檢查點發生之後資料庫的資料檔案、控制檔案處於一致狀態的含義是不需要進行 介質恢復,只表示資料檔案頭一致,但是並不表示資料檔案內容一致,因為資料檔案內容可能在沒有發生檢查點的其他情況下的dbwr寫資料檔案,這樣資料檔案內容就不一致,若掉電需要進行崩潰恢復。

檢查點是一個資料庫事件,它把修改資料從快取記憶體寫入磁碟,並更新控制檔案和資料檔案。

檢查點分為三類:
1)區域性檢查點:單個例項執行資料庫所有資料檔案的一個檢查點操作,屬於此例項的全部髒快取區寫入資料檔案。
觸發命令:
svmrgrl>alter system checkpoint local;
這條命令顯示的觸發一個區域性檢查點。
2)全域性檢查點:所有例項(對應並行資料伺服器)執行資料庫所有資料檔案的一個檢查點操作,屬於此例項的全部髒快取區寫入資料檔案。
觸發命令
svrmgrl>alter system checkpoint global;
這條命令顯示的觸發一個全域性檢查點。
3)檔案檢查點:所有例項需要執行資料檔案集的一個檢查點操作,如使用熱備份命令alter tablespace USERS begin backup,或表空間離線命令alter tablespace USERS offline,將執行屬於USERS表空間的所有資料檔案的一個檢查點操作。

檢查點處理步驟:
1)獲取例項狀態佇列:例項狀態佇列是在例項狀態轉變時獲得,ORACLE獲得此佇列以保證檢查點執行期間,資料庫處於開啟狀態;
2)獲取當前檢查點資訊:獲取檢查點記錄資訊的結構,此結構包括當前檢查點時間、活動執行緒、進行檢查點處理的當前執行緒、日誌檔案中恢復截止點的地址資訊;
3)快取區標識:標識所有髒快取區,當檢查點找到一個髒快取區就將其標識為需進行重新整理,標識的髒快取區由系統程式DBWR進行寫操作,將髒快取區的內容寫入資料檔案;
4)髒快取區重新整理:DBWR程式將所有髒快取區寫入磁碟後,設定一標誌,標識已完成髒快取區至磁碟的寫入操作。系統程式LGWR與CKPT程式將繼續進行檢查,直至DBWR程式結束為止;
5)更新控制檔案與資料檔案。
注:控制檔案與資料檔案頭包含檢查點結構資訊。
在兩種情況下,檔案頭中的檢查點資訊(獲取當前檢查點資訊時)將不做更新:
1)資料檔案不處於熱備份方式,此時ORACLE將不知道作業系統將何時讀檔案頭,而備份複製在複製開始時必須具有檢查點SCN;
ORACLE在資料檔案頭中保留一個檢查點的記數器,在正常操作中保證使用資料檔案的當前版本,在恢復時防止恢復資料檔案的錯誤版本;即使在熱備份方式下,計數器依然是遞增的;每個資料檔案的檢查點計數器,也保留在控制檔案相對應資料檔案項中。
2)檢查SCN小於檔案頭中的檢查點SCN的時候,這表明由檢查點產生的改動已經寫到磁碟上,在執行全域性檢查點的處理過程中,如果一個熱備份快速檢查點在更新檔案頭時,則可能發生此種情況。應該注意的是,ORACLE是在實際進行檢查點處理的大量工作之前捕獲檢查SCN的,並且很有可能被一條象熱備份命令 alter tablespace USERS begin backup進行快速檢查點處理時的命令打斷。
ORACLE在進行資料檔案更新之前,將驗證其資料一致性,當驗證完成,即更新資料檔案頭以反映當前檢查點的情況;未經驗證的資料檔案與寫入時出現錯誤的資料檔案都被忽略;如果日誌檔案被覆蓋,則這個檔案可能需要進行介質恢復,在這種情況下,ORACLE系統程式DBWR將此資料檔案離線。

檢查點演算法描述:
髒快取區用一個新佇列連結,稱為檢查點佇列。對快取區的每一個改動,都有一個與其相關的重做值。檢查點佇列包含髒的日誌快取區,這些快取區按照它們在日誌檔案中的位置排序,即在檢查點佇列中,快取區按照它們的低重做值進行排序。需要注意的是,由於快取區是依照第一次變髒的次序連結到佇列中的,所以,如果在快取區寫出之前對它有另外的改動,連結不能進行相應變更,快取區一旦被連結到檢查點佇列,它就停留在此位置,直到將它被寫出為止。

ORACLE系統程式DBWR在響應檢查點請求時,按照這個佇列的低重做值的升序寫出快取區。每個檢查點請求指定一個重做值,一旦DBWR寫出的快取區重做值等於或大雨檢查點的重做值,檢查點處理即完成,並將記錄到控制檔案與資料檔案。
由於檢查點佇列上的快取區按照低重做值進行排序,而DBWR也按照低重做值順序寫出檢查點快取區,故可能有多個檢查點請求處於活動狀態,當DBWR寫出快取區時,檢查位於檢查點佇列前端的快取區重做值與檢查點重做值的一致性,如果重做值小於檢查點佇列前快取區的低重做值的所有檢查點請求,即可表示處理完成。當存在未完成的活動檢查點請求時,DBWR繼續寫出檢查點快取區。

演算法特點:
1)DBWR能確切的知道為滿足檢查點請求需要寫那些快取區;
2)在每次進行檢查點寫時保證指向完成最早的(具有最低重做值的)檢查點;
3)根據檢查點重做值可以區別多個檢查點請求,然後按照它們的順序完成處理。

二、SCN

SCN(System Chang Number)作為oracle中的一個重要機制,在資料恢復、Data Guard、Streams複製、RAC節點間的同步等各個功能中起著重要作用。理解SCN的運作機制,可以幫助你更加深入地瞭解上述功能。

1、系統檢查點scn
當一個檢查點動作完成後,Oracle就把系統檢查點的SCN儲存到控制檔案中。
select checkpoint_change# from v$database
2、資料檔案檢查點scn
當一個檢查點動作完成後,Oracle就把每個資料檔案的scn單獨存放在控制檔案中。
select name,checkpoint_change# from v$datafile
3、啟動scn
Oracle把這個檢查點的scn儲存在每個資料檔案的檔案頭中,這個值稱為啟動scn,因為它用於在資料庫例項啟動時,檢查是否需要執行資料庫恢復。
select name,checkpoint_change# from v$datafile_header
4、終止scn
每個資料檔案的終止scn都儲存在控制檔案中。
select name,last_change# from v$datafile
在正常的資料庫操作過程中,所有正處於聯機讀寫模式下的資料檔案的終止scn都為null.
5、在資料庫執行期間的scn值
在資料庫開啟並執行之後,控制檔案中的系統檢查點、控制檔案中的資料檔案檢查點scn和每個資料檔案頭中的啟動scn都是相同的。控制檔案中的每個資料檔案的終止scn都為null.
在安全關閉資料庫的過程中,系統會執行一個檢查點動作,這時所有資料檔案的終止scn都會設定成資料檔案頭中的那個啟動scn的值。在資料庫重新啟動的時候,Oracle將檔案頭中的那個啟動scn與資料庫檔案檢查點scn進行比較,如果這兩個值相互匹配,oracle接下來還要比較資料檔案頭中的啟動 scn和控制檔案中資料檔案的終止scn。如果這兩個值也一致,就意味著所有資料塊多已經提交,所有對資料庫的修改都沒有在關閉資料庫的過程中丟失,因此這次啟動資料庫的過程也不需要任何恢復操作,此時資料庫就可以開啟了。當所有的資料庫都開啟之後,儲存在控制檔案中的資料檔案終止scn的值再次被更改為 null,這表示資料檔案已經開啟並能夠正常使用了。

三、事務過程

我們再看下oracle事務中的資料變化是如何寫入資料檔案的:

1、 事務開始;

2、 在buffer cache中找到需要的資料塊,如果沒有找到,則從資料檔案中載入buffer cache中;

3、 事務修改buffer cache的資料塊,該資料被標識為“髒資料”,並被寫入log buffer中;

4、 事務提交,LGWR程式將log buffer中的“髒資料”寫入redo log file中;

5、 當發生checkpoint,CKPT程式更新所有資料檔案的檔案頭中的資訊,DBWn程式則負責將Buffer Cache中的髒資料寫入到資料檔案中。

經過上述5個步驟,事務中的資料變化最終被寫入到資料檔案中。但是,一旦在上述中間環節時,資料庫意外當機了,在重新啟動時如何知道哪些資料已經寫入資料檔案、哪些沒有寫呢(同樣,在DG、streams中也存在類似疑問:redo log中哪些是上一次同步已經複製過的資料、哪些沒有)?SCN機制就能比較完善的解決上述問題。

SCN是一個數字,確切的說是一個只會增加、不會減少的數字。正是它這種只會增加的特性確保了Oracle知道哪些應該被恢復、哪些應該被複制。

總共有4中SCN:系統檢查點(System Checkpoint)SCN、資料檔案檢查點(Datafile Checkpoint)SCN、結束SCN(Stop SCN)、開始SCN(Start SCN)。其中其面3中SCN存在於控制檔案中,最後一種則存在於資料檔案的檔案頭中。

在控制檔案中,System Checkpoint SCN是針對整個資料庫全域性的,因而只存在一個,而Datafile Checkpoint SCN和Stop SCN是針對每個資料檔案的,因而一個資料檔案就對應在控制檔案中存在一份Datafile Checkpoint SCN和Stop SCN。在資料庫正常執行期間,Stop SCN(透過檢視v$datafile的欄位last_change#可以查詢)是一個無窮大的數字或者說是NULL。

在一個事務提交後(上述第四個步驟),會在redo log中存在一條redo記錄,同時,系統為其提供一個最新的SCN(透過函式 dbms_flashback.get_system_change_number可以知道當前的最新SCN),記錄在該條記錄中。如果該條記錄是在 redo log被清空(日誌滿做切換時或發生checkpoint時,所有變化日誌已經被寫入資料檔案中),則其SCN被記錄為redo log的low SCN。以後在日誌再次被清空前寫入的redo記錄中SCN則成為Next SCN。

當日志切換或發生checkpoint(上述第五個步驟)時,從Low SCN到Next SCN之間的所有redo記錄的資料就被DBWn程式寫入資料檔案中,而CKPT程式則將所有資料檔案(無論redo log中的資料是否影響到該資料檔案)的檔案頭上記錄的Start SCN(透過檢視v$datafile_header的欄位checkpoint_change#可以查詢)更新為Next SCN,同時將控制檔案中的System Checkpoint SCN(透過檢視v$database的欄位checkpoint_change#可以查詢)、每個資料檔案對應的Datafile Checkpoint(透過檢視v$datafile的欄位checkpoint_change#可以查詢)也更新為Next SCN。但是,如果該資料檔案所在的表空間被設定為read-only時,資料檔案的Start SCN和控制檔案中Datafile Checkpoint SCN都不會被更新。

四、心跳

在Oracle中有一個事件叫Heartbeat,這個詞在很多地方被提及,並且有著不同的含義(比如RAC中),我們這裡要討論的是CKPT的Heartbeat機制。

Oracle透過CKPT程式每3秒將Heartbeat寫入控制檔案,以減少故障時的恢復時間。

我們可以透過如下方法驗證這個過程。

1.首先在系統級啟用10046時間跟蹤

並重新啟動資料庫使之生效

[oracle@jumper oracle]$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Thu Jan 19 09:24:04 2006
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Connected to:Oracle9i Enterprise Edition Release 9.2.0.4.0 - ProductionWith the Partitioning optionJServer Release 9.2.0.4.0 - Production
SQL> alter system set event='10046 trace name context forever,level 12' scope=spfile;
System altered.
SQL> shutdown immediate;Database closed.Database dismounted.ORACLE instance shut down.
SQL> startupORACLE instance started.
Total System Global Area  114365800 bytesFixed Size                   451944 bytesVariable Size              50331648 bytesDatabase Buffers           62914560 bytesRedo Buffers                 667648 bytesDatabase mounted.Database opened.SQL> exitDisconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 -
ProductionWith the Partitioning optionJServer Release 9.2.0.4.0 - Production
2.檢查bdump目錄下生成的跟蹤檔案

目錄在$ORACLE_HOME/admin/$ORACLE_SID/bdump目錄下,每個後臺程式都會生成一個跟蹤檔案。

[oracle@jumper bdump]$ ls20050424_alert_conner.log  conner_arc0_2569.trc 
conner_dbw0_2559.trc  conner_reco_2567.trcalert_conner.log           conner_arc1_2571.trc
 conner_lgwr_2561.trc  conner_smon_2565.trca.sql                      conner_ckpt_2563.trc
 conner_pmon_2557.trc
3.檢查CKPT程式的跟蹤檔案

我們可以很容易的發現CKPT程式每3秒都對控制檔案進行一次寫入

[oracle@jumper bdump]$ tail -f conner_ckpt_2563.trc WAIT #0: nam='rdbms ipc message' ela= 2994710 p1=300 p2=0 p3=0WAIT #0: nam='control file parallel write' ela= 2442 p1=3 p2=3 p3=3WAIT #0: nam='rdbms ipc message' ela= 2995171 p1=300 p2=0 p3=0WAIT #0: nam='control file parallel write' ela= 2586 p1=3 p2=3 p3=3WAIT #0: nam='rdbms ipc message' ela= 2994962 p1=300 p2=0 p3=0WAIT #0: nam='control file parallel write' ela= 2582 p1=3 p2=3 p3=3WAIT #0: nam='rdbms ipc message' ela= 2995020 p1=300 p2=0 p3=0WAIT #0: nam='control file parallel write' ela= 2455 p1=3 p2=3 p3=3WAIT #0: nam='rdbms ipc message' ela= 2995188 p1=300 p2=0 p3=0WAIT #0: nam='control file parallel write' ela= 2412 p1=3 p2=3 p3=3WAIT #0: nam='rdbms ipc message' ela= 2995187 p1=300 p2=0 p3=0WAIT #0: nam='control file parallel write' ela= 2463 p1=3 p2=3 p3=3WAIT #0: nam='rdbms ipc message' ela= 2995095 p1=300 p2=0 p3=0WAIT #0: nam='control file parallel write' ela= 2448 p1=3 p2=3 p3=3
4.檢查控制檔案的變更

透過2次dump控制檔案,比較其trace檔案輸出可以比較得到不同之處,我們發現,Oracle僅僅更新了Heartbeat這個數值。

[oracle@jumper udump]$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Wed Jan 18 22:44:10 2006
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to:Oracle9i Enterprise Edition Release 9.2.0.4.0 - ProductionWith the Partitioning optionJServer Release 9.2.0.4.0 - Production
SQL> alter session set events 'immediate trace name CONTROLF level 10';
Session altered.
SQL> exitDisconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - ProductionWith the Partitioning optionJServer Release 9.2.0.4.0 - Production[oracle@jumper udump]$ sqlplus "/ as sysdba"
SQL*Plus: Release 9.2.0.4.0 - Production on Wed Jan 18 22:44:18 2006
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to:Oracle9i Enterprise Edition Release 9.2.0.4.0 - ProductionWith the Partitioning optionJServer Release 9.2.0.4.0 - Production
SQL> alter session set events 'immediate trace name CONTROLF level 10' ;
Session altered.
SQL> exitDisconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - ProductionWith the Partitioning optionJServer Release 9.2.0.4.0 - Production
[oracle@jumper udump]$ lsconner_ora_21896.trc conner_ora_21898.trc[oracle@jumper udump]$ diff conner_ora_21896.trc conner_ora_21898.trc 1c1< /opt/oracle/admin/conner/udump/conner_ora_21896.trc---&gt /opt/oracle/admin/conner/udump/conner_ora_21898.trc14c14< Unix process pid: 21896, image: oracle@jumper.hurray.com.cn (TNS V1-V3)---&gt Unix process pid: 21898, image: oracle@jumper.hurray.com.cn (TNS V1-V3)16c16< *** SESSION ID9.813) 2006-01-18 22:44:14.314---&gt *** SESSION ID9.815) 2006-01-18 22:44:21.569
63c63< heartbeat: 579991793 mount id: 3191936000---&gt heartbeat: 579991796 mount id: 3191936000 [oracle@jumper udump]$

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

相關文章