初學checkpoint and scn

RAYSUNNNY發表於2013-12-20


關於備份恢復這一塊,經常要使用SCN來分析問題,SCN跟CHECKPOINT好像又有著一些聯絡.當然在網上已經有很多前輩做過總結,在這我參考了許多前輩的資料,自己就scn和checkpiont也做一個小小的總結,希望這樣能加深自己的印象,也跟大家分享,如果有錯誤,望大家不吝指教。
SCN和Checkpoint的確是一個難點,但他們對oracle資料庫有著非常重要的意義。下面我會對scn和checkpoint分別做介紹,然後再看看他們之間有沒有一些聯絡。
先說SCN
SCN的意義:SCN是系統改變號(SYSTEM CHANGE NUMBER),是一個數值,它其實相當於一個時間,ORACLE資料庫用它來記錄資料庫的變化,SCN之間可以進行比較以得出對資料庫的各種操作的先後。
SCN的種類:主要常見的有4種
1.System Checkpoint SCN 系統檢測點SCN 
檢視:select checkpoint_change# from v$database;
2.Datafile Checkpoint SCN 資料檔案檢查點SCN
檢視:select name,checkpoint_change# from v$datafile;
3.Start SCN 開始SCN
檢視:select name,checkpoint_change# from v$datafile_header; 
4.Stop SCN 結束SCN
檢視:select name,last_change# from v$datafile;
那麼這常見的4種SCN是存放在哪,有什麼用呢?
存放位置:系統檢測點SCN 資料檔案檢查點SCN 結束SCN 是存放在控制檔案中的,而開始SCN存放在資料檔案的頭部
注意:每個資料檔案頭部都有開始SCN,而ORACLE中有多少個資料檔案,在控制檔案中就有對應有多少個資料檔案檢查點SCN和結束SCN而系統檢查點SCN只有一個
SCN的作用:
在說作用之前,應該先講他們的初始值。
資料庫在正常執行時,系統檢測點SCN 資料檔案檢查點SCN以及開始SCN是一樣的,而結束SCN為空。這是資料庫正常執行的狀態
那麼從資料庫啟動開始說起。資料庫開啟分(nomount mount open)3個階段。
在資料庫要開啟時(open),ORACLE會檢查所有資料檔案頭部的開始SCN,拿它和控制檔案中的資料檔案檢查點SCN比較(我們說過SCN是一個數值)。如果相同,它就繼續看控制檔案中的Stop SCN,如果Stop SCN和Start SCN相同,那麼資料庫就能正常開啟。如果Stop SCN和Start SCN不同,則資料庫需要做例項恢復。如果在前面比較控制檔案中的資料檔案檢查點SCN和資料檔案頭部的SCN時就出現了不同,那麼資料庫就會做介質恢復。
之所以會這樣,是因為【資料庫正常執行時System Checkpoint SCN=Datafile Checkpoint SCN=Start SCN,Stop=null】這我們前面講過
如果資料庫正常關閉:shutdown normal/immediate/transactional ,系統會發生完全檢查點(這我們在下面再講),把控制檔案中的Stop SCN改為資料檔案頭部的Start SCN再關閉資料庫。也就是說正常關閉資料庫的話,我們重啟資料庫檢查這4個SCN他們都是一樣的,能正常開啟。
如果資料庫非正常關閉,shutdown abort,掉電等,ORACLE沒來得及將Stop SCN置為和Start SCN一樣,那麼在重新開啟資料庫是,檢查這4個SCN,會發現Stop SCN 的置為空
ORACLE就知道資料庫非正常關閉,需要做例項奔潰恢復。
還有一種情況,就是我們資料庫是正常關閉,但是我們由於一個資料檔案丟了,我們用一個備份的資料檔案來恢復到原來位置,但是它是備份的,檔案頭部的Start SCN 非常有可能是小於現在資料庫使用的控制檔案中的各個SCN值,那麼資料庫就會提醒我們做介質恢復。
上面這些就是資料庫利用SCN值來判斷是否需要做恢復,做哪種恢復的原理。需要注意的是,資料庫是先判斷Start SCN值是否與現有的其他SCN相等,再判斷Stop SCN。也就是說,如果資料庫既需介質恢復,又需例項奔潰恢復時,是先做介質恢復的。
SCN是什麼時候變化的:在上面說過,資料庫正常關閉時會發生完全檢查點,將Stop SCN置為和Start SCN一樣。這時Stop SCN改變。那麼其他的3個SCN值會改變嗎?他們什麼時候改變呢?
其實在資料庫中還有2種常用的SCN
1.日誌檔案頭部帶有low SCN和 next SCN
(每條日誌記錄都有一個SCN號)
日誌檔案的頭部中的low SCN 和 next SCN是用來做資料庫恢復用的。low SCN代表該日誌檔案最早一條日誌所對應的SCN,next SCN代表該日誌檔案最後一條日誌所對應的SCN。
也就是說該日誌檔案是可以用來恢復 SCN值在LOW SCN 到NEXT SCN之間的事物和資料改變的。

日誌檔案有三種狀態,inactive,active,current
inactive代表這個日誌檔案裡面沒資料或者可以被覆蓋,active代表這個日誌檔案裡面有資料,而且對應的在SGA裡面的buffer cache還沒有寫到磁碟。也就是說該日誌檔案不能被覆蓋,因為對應的緩衝資料還沒寫到磁碟,如果系統奔潰,到時還需要使用到該日誌檔案進行恢復,所以不能覆蓋。current代表該日誌檔案正在被使用也不能被覆蓋。
2.系統當前的current SCN
系統當前的SCN號不一定是和檔案頭部和控制檔案中的那些SCN號相等的,它是在不斷改變的。它改變的觸發條件有很多,這裡就不具體說了。可以使用檢視 select current_scn from v$database;

我們這裡是要講上面4種SCN上面時候變化的(當然Stop SCN我們已經知道什麼時候變化了),那麼還有3種(Start SCN,System Checkpoint SCN,Datafile Checkpoint SCN)它們在資料庫正常執行期間是要保持相同的,所以改變時它們也是同步改變的。(Start SCN,System Checkpoint SCN,Datafile Checkpoint SCN),他們是與最近一次執行完全檢查點時的那個SCN值相等的,至於什麼時候執行完全檢查點,我們下面會講。而且這個SCN值是大於等於當前最老的active或current日誌所對應的First_change#.意思就是如果控制檔案和資料檔案要做恢復時,是要使用控制檔案和資料檔案中三個SCN值所對應的大於等於first scn的日誌檔案開始恢復。
比如:
在資料庫正常執行期間
--檢視系統當前的System Checkpoint SCN


--檢視當前日誌的情況

--可以看出,System Checkpoint SCN等於 current日誌的first_change#
--現在切換日誌2次(會發生完全檢查點),重新檢視日誌檔案和System Checkpoint SCN

發現System Checkpoint SCN等於 active日誌序列號為11的日誌的first_change#,說明此時DBWR還沒將髒塊寫到資料檔案,這些日誌還不能被覆蓋,到時奔潰恢復時,我們需要根據System Checkpoint SCN 找到對應的日誌檔案,再根據lrba(下面檢查點佇列會講)找到日誌記錄開始恢復。
讓我們不做任何操作等待一段時間,這段時間內,DBWR會觸發(每隔三秒或其他觸發條件),把髒資料寫到磁碟,對應的日誌檔案也會從active變成inactive。那麼我們再來查一下日誌檔案和System Checkpoint SCN

不出所料,原來2個ACTIVE日誌檔案變成了inactive狀態。而System Checkpoint SCN記錄的是大於等於最早的active或current日誌檔案中的low SCN(FIRST_CHANGE#)。
那麼此時它等於current日誌的first_change#.Start SCN,System Checkpoint SCN,Datafile Checkpoint SCN)。
注意:最早的active日誌中的最早指的是sequecce#值最小的。切換日誌之後,並不會立即更新SCN,要等DBWR寫完需要寫的髒塊後,完全檢查點才完成並將SCN更新到控制檔案和資料檔案頭部。

如:我設定log_checkpoints_to_alert引數為TRUE,這麼資料庫發生的檢查點資訊都會記錄到警告檔案中。我執行切換日誌操作(alter system switch logfile),檢視警告檔案,裡面寫到

在19點47分時開始切換日誌到檢查點位置 指定(RBA [0x15.2.10] SCN:1497417),此時去查控制檔案的各個SCN它還是保持和之前的一樣。但是在19:52分時,完全檢查點完成,然後記錄了RBA和SCN到控制檔案。

這時再去查控制檔案中的SCN就等於1497417.


相信大家都注意到了,我們這3個SCN值是一般情況是一樣的,Start SCN=System Checkpoint SCN=Datafile Checkpoint SCN
Start SCN用於判斷資料檔案是否是舊的,用於判斷是否進行資料檔案介質恢復。而System Checkpoint SCN和Datafile Checkpoint SCN是否重複呢?
使用一個可以嗎?答案是不可以
我查了一些資料,下面是解釋:
1.對只讀表空間,其資料檔案的Datafile Checkpoint SCN、Start SCN和END SCN號均相
同。這三個 SCN在表空間處於只讀期間都將被凍結。
2.如果控制檔案不是當前的控制檔案,則System checkpoint會小於Start SCN或END SCN
號。
記錄這些SCN號,可以區分控制檔案是否是當前的控制檔案。

終於講完scn了,可能講的不是很清楚!!!

下面是檢查點。
什麼是檢查點佇列(Checkpoint queue)?
檢查點佇列是存在於SGA中,它是一個連結串列,連結著BUFFER CACHE中的髒塊,每個資料塊上都有一個buffer header,在這個頭部裡面有一個ckptq項,它可以記錄檢查點佇列的上一個塊地址和下一個塊地址
而檢查點佇列是按照一個髒塊第一次被髒的時間點鏈起來的。
例如:現在有4個髒塊,d1,d2,d3,d4,他們被髒的時刻分別為
d1         7:30:14
d2         7:30:50 
d3         7:31:01
d4         7:31:30
d1         7:32:00
d3         7:32:01
我們假設在這個時間段內DBWR並沒有將這4個髒塊寫到磁碟,(DBWR會因很多原因觸發),那麼我們看到在7:32:00後時刻,d1和d3塊又被髒了一次,但是資料庫裡的檢查點佇列上面的排列順序任然是 d1->d2->d3->d4,這就是檢查點佇列。
接下來講檢查點,檢查點有2種
1.完全檢查點
在上面講到SCN時我們已經說過,完全檢查點發生在資料庫正常關閉時,在資料庫正常執行過程中,完全檢查點幾乎不發生。在發生完全檢查點時,ckpt(檢查點程式)會觸發DBWR把資料庫中發生檢查點之前的SCN對應的髒資料寫到磁碟。然後會用發生檢查點時的SCN更新控制檔案中的系統檢查點SCN,資料檔案檢查點SCN和資料檔案頭部開始SCN。而這裡有個心跳的概念,每隔三秒,CKPT會去檢視dbwr寫到什麼位置了,然後把對應的塊的lrba地址寫到控制檔案。

注意:如果對應的是由於正常關機引起的完全檢查點還會用每個資料檔案頭部的Start SCN 更新控制檔案中的Stop SCN。

完全檢查點觸發條件:

1.資料庫正常關機。
2.alter tablespace tablespace_name offline;將表空間離線

3.Alter system switch logfile;

4.alter system checkpoint;手動執行完全檢查點

5.相關引數的設定LOG_CHECKPOINT_INTERVAL, LOG_CHECKPOINT_TIMEOUT ,FAST_START_IO_TARGET 

注意:alter database datafile ‘dir’ offline;不會發生檢查點 
2.增量檢查點
下面是參考Dave部落格http://blog.csdn.net/tianlesoftware/article/details/6700085的關於增量檢查點的英文文件
 Incremental Checkpoint
? Writes the contents of “some” dirty buffers to the database from CKPT-Q
? Block images written in SCN order
? Checkpoint RBA updated in SGA
? Statistics updated:
– DBWR checkpoint buffers written
? Controlfile is updated every 3 seconds byCKPT
– Checkpoint progress record

Definition of “Some”
? Every 3 seconds CKPT calculates thecheckpoint
target RBA based on:
– The most current RBA
– log_checkpoint_timeout
– log_checkpoint_interval
– fast_start_mttr_target
– fast_start_io_target
– 90% of the size of the smallest onlineredo log file
? All buffers dirtied prior to the timecorresponding to the target RBA are written to the database

大體意思是: CKPT程式平時會檢查(ckpt-Q)檢查點佇列是否過長,會觸發DBWR寫“一部分”髒塊到磁碟,DBWR是按照(ckpt-Q)檢查點佇列的先後寫的,增量檢查點發生時,會往控制檔案中寫入當前檢查點佇列的第一塊的lrba地址,(lrba地址指的是該塊第一次被髒所對應的日誌地址,這裡不詳細講,大家可以參考網上很多前輩的文章),然後還有個心跳的概念。
上面講得有些亂,下面總結一下到底上面是增量檢查點,它到底做了些什麼。

當觸發增量檢查點時,
CKPT程式會根據一套方法(具體是根據一些引數的設定SCN,I/O繁忙度),去檢查檢查點佇列是否過長,計算出一個target RBA,然後CKPT會通知DBWR“你去將我檢查點佇列上的lrba地址等於target RBA的所對應的髒塊之前的塊資料寫到磁碟),然後DBWR就去寫資料了。那麼此時CKPT的第一個任務就結束了,注意它不會去等待DBWR去做完它給的任務,到此它的第一個任務就完成了。

那麼DBWR在寫資料了,CKPT怎樣知道他寫完了沒,或者說寫到哪個塊了呢?原來,有一個心跳的概念,即每隔三秒鐘,CKPT會去檢查一次DBWR寫到哪個位置了,同時還把此時剛寫完的dirty buffer對應的lrba記錄到控制檔案,這個就是檢查點位置這就是CKPT的第二個任務了。

那麼這2個任務所組合起來完成的任務就是增量檢查點做的任務。當CKPT觸發DBWR寫資料,然後CKPT每3秒將檢查點位置更新到控制檔案中,就完成了一個增量檢查點。(注意增量檢查點並不更新控制檔案和資料檔案頭部的SCN)
增量檢查點觸發條件:

1. 在聯機熱備份資料檔案前,要求該資料檔案中被修改的塊從DB_Buffer 寫入資料檔案中。所以,發出這樣的命令:

ALTER TABLESPACE tablespace_name BIGEN BACKUP & end backup; 也將觸發和該表空間的資料檔案有關的區域性檢查點;

2.alter tablespace name read only;

3.Alter tablespace name offline normal;(與alter tablespace name offline發生完全檢查點做區分)
還得講講檢查點的意義:
很簡單,系統會由於我們的各種操作,離線表空間,資料檔案手動執行檢查點還有初始化引數等原因觸發檢查點,其意義
將SGA中髒塊寫到磁碟,不要讓太多髒塊堆積在SGA中,最終目的還是保護資料庫的一致性和完整性。想一下,如果資料庫掉電,當機了
我們重啟時一定要做恢復,如果有大量的髒塊本來在SGA中,現在丟了,是不是恢復起來速度很慢?那麼要做恢復,需要日誌,那麼資料庫怎麼知道我用
哪些日誌做恢復,做什麼型別的恢復呢?這就是檢查點發生時往控制檔案資料檔案頭部寫的檢查點scn和檢查點位置(lrba)起作用了。


資料庫在需要做恢復時的步驟
上面講過SCN做恢復時,系統採取的措施和步驟
現在是結合檢查點和SCN,系統真正做恢復時是這樣進行操作的。
1.重啟資料庫,檢查各個檔案的SCN值(開始SCN,結束SCN,系統檢查點SCN,資料檔案檢查點SCN),確定要做介質恢復還是例項奔潰恢復
2.如果確定要做恢復,根據檢查點SCN值找到對應的日誌檔案,然後再根據檢查點位置(lrba)找到該日誌檔案的對應記錄,開始跑日誌,做恢復。

最後做一個實驗,目的是看看SCN和檢查點之間的聯絡,即我們手動執行檢查點後,資料檔案頭部和控制檔案中的SCN應該會和我們執行檢查點時的SCN一樣。
資料庫在正常執行期間,DBWR往資料庫磁碟寫資料不一定都是因為發生檢查點,CKPT觸發DBWR寫資料,即既有非檢查點,又有檢查點
現在我們檢視系統當前的控制檔案中的各個SCN,還有資料檔案頭的Start SCN
這裡我們只查System Checkpoint SCN,其他的都和它一樣,當然Stop SCN為空

--檢視日誌檔案

大家看這System Checkpoint SCN和active日誌對應的SCN不同(大於)。的確,因為我在檢視System Checkpoint SCN之前手動執行了檢查點,所以System Checkpoint SCN記錄的是我當時執行檢查點時的SCN。在資料庫正常執行期間,有時會自動發生檢查點,有時是人為操作導致檢查點發生,那麼這時控制檔案和資料檔案頭部的SCN就不一定等於最早的active或current日誌的low scn了。

--我們再次手動執行檢查點,再檢視當前scn

檢視控制檔案中的系統檢查點SCN

沒錯,1459985正是我們執行檢查點時的SCN。
初學oracle,多以總結為主,如有遺漏錯誤,希望指正。



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