checkpoint和SCN有什么關系?
Checkpoint
很多人都把checkpoint的概念給復雜化了,其實checkpoint這個數據庫概念引入的真正意義就是用來減少在數據庫恢復過程中所花的時間(instance recovery),那么checkpoint是又誰來做的呢?我們都知道數據庫中有個CKPT進程,這個是個可選進程,但是真正執行檢查點的任務并不是有ckpt來完成的,而是ckpt在更新控制文件和數據文件頭的有關信息后,通知DBWn進程,產生一個檢查點,在產生檢查點的時候,DBWn進程會將buffer cache中的臟數據(當前online redo log對應的臟數據),寫入我們的數據文件當中。那么這個時候如果數據庫此時崩潰(比如我們做個shutdown abort),那么在進行實例恢復的時候就可以不需要當前online redo log的內容了,會很快就做完。因此ckpt進程只是個輔助進程,他的任務更多的是用來在系統做checkpoint的時候更新控制文件和數據文件頭中的信息。其實在oracle 8i的時候呢,ckpt的任務一般都是由lgwr進程來完成,到了8i以后,隨著CKPT進程的引入,lgwr的工作負擔就減輕了很多(commit的速度加快了)
那么如何來產生檢查點呢?
有三種方法,可以通過
1.alter system checkpoint
2.alter system switch logfile
3.DBWn進程寫出臟塊
SCN
在Oracle中理解為一個內部同步時鐘,是系統改變號的縮寫(system change number),在Oracle數據庫中我們可以通過dbms_flashback包來查詢當前系統的改變號:select dbms_flashback.get_system_change_number from dual;一般來講SCN主要是用來標識數據庫所做的所有改變,這個SCN的改變是只能前進,不能回退,除非我們打算重建庫,數據庫中的SCN永遠不會歸0,一般來說SCN的前進觸發是由commit來進行的,除了這些據我觀察每隔3秒種系統也都會刷新一次SCN.
需要注意的是:
1.CKPT一定是是在checkpoint發生的時候將數據庫當前的SCN更新入數據庫文件頭和控制文件當中,同時DBWn進程將buffer
cache中的臟數據塊(dirty block)寫到數據文件當中(這個臟數據也一定是當前online redo
log保護的那一部分)。2.同時CKPT進程還會在控制文件當中記錄(redo block
address)RBA,這個地址用來標志恢復的時候需要從日志中的那個位置開始。
在Oracle數據庫中和checkpoint相關的SCN總共有4個
1.System checkpoint SCN (存在于控制文件)
在系統執行checkpoint后,Oracle會更新當前控制文件中的System checkpoint SCN。
我們可以通過
select checkpoint_change# from v$database:
來查看
2.Datafile checkpoint SCN (存在于控制文件)
由于控制文件中記錄了Oracle中各個數據庫文件的位置和信息,其中當然也包括了Datafile
checkpoint SCN,因此在執行checkpoint的時候,Oracle還會去更新控制文件中所記錄的各個數據文件的datafile
checkpoint SCN.
我們可以通過
select checkpoint_change# from v$datafile;
來查看
3.Start SCN (存在于各個數據文件頭)
在執行checkpoint時,Oracle會更新存放在各個實際的數據文件頭的Start SCN(注意絕對不會是控制文件中),這個SCN存在的目的是用于檢查數據庫啟動過程中是否需要做media recovery(介質恢復)
我們可以通過
select checkpoint_change# from v$datafile_header;
4.End SCN(存在于控制文件)
最后一類SCN,End
SCN他也是記錄在控制文件當中,每一個所記錄的數據文件頭都有一個對應的End SCN,這個End
SCN一定是存在于控制文件當中。這個SCN存在的絕對意義主要是用來去驗證數據庫啟動過程中是否需要做instance
recovery。我們可以通過
select name,last_change# from v$datafile
那么其實在數據庫正常運行的情況下,對于read/write的online 數據文件這個SCN號為#FFFFFF(NULL).
下面來聊一聊SCN號于數據庫的啟動
1.在數據庫的啟動過程中,當System
Checkpoint SCN=Datafile Checkpoint SCN=Start
SCN的時候,Oracle數據庫是可以正常啟動的,而不需要做任何的media recovery。而如果三者當中有一個不同的話,則需要做media
recovery
2.那什么時候需要做instance
recovery呢?其實在正常open數據庫的時候,oracle會將記錄在控制文件中的每一個數據文件頭的End
SCN都設置為#FFFFFF(NULL),那么如果數據庫進行了正常關閉比如(shutdown or shutdown
immediate)這個時候,系統會執行一個檢查點,這個檢查點會將控制文件中記錄的各個數據文件頭的End
SCN更新為當前online數據文件的各個數據文件頭的Start SCN,也就是End SCN=Start
SCN,如果再次啟動數據庫的時候發現二者相等,則直接打開數據庫,并再次將End
SCN設置為#FFFFFF(NULL),那么如果數據庫是異常關閉,那么checkpoint就不會執行,因此再次打開數據庫的時候End
SCN<>Start SCN這個時候就需要做實例恢復。
說了那么多更新SCN操作什么的,這個更新操作到底是由誰做的呢?其實剛才已經說過了,就是我們的CKPT進程,他不僅僅會更新SCN,而且還會通知DBWn做他的事情。
再說一下System Checkpoint SCN和Datafile Checkpoint SCN,這兩個SCN都是記錄在控制文件當中的。但是這兩個SCN有什么作用呢?
logzgh有段論述,我自己的想了一下,還是學習一下他的結論:
1.對只讀表空間,其數據文件的Datafile Checkpoint SCN、Start SCN和END SCN號均相同。這三個SCN在表空間處于只讀期間都將被凍結。
2.如果控制文件不是當前的控制文件(其實就是說,想比當前redo
log的SCN來講,控制文件已經過時了),則System checkpoint SCN會小于Start SCN(Start
SCN是來自實際的數據文件頭,有比較依據)。記錄這些SCN號,可以區分控制文件是否是當前的控制文件。當有一個Start
SCN(從當前各個在線數據文件中獲得)號超過了System Checkpoit
SCN號時,則說明控制文件不是當前的控制文件,因此在做recovery時需要采用using backup
controlfile。這是為什么需要記錄SystemCheckpoint SCN的原因之一。
當我們重建控制文件的時候,重建方式分兩種(resetlogs 和 noresetlogs)
1.使用resetlogs選項時,System
Checkpoint SCN為被歸為0,而其中記錄的各個數據文件的Datafile Checkpoint SCN則來自于Start
SCN(也就是說可能會從冷備份的數據文件的數據文件頭中獲取)。根據上述的描述,此時需要采用using backup
controlfile做recovery. 因此情況是 System Checkpoint SCN=0 < Start SCN =
Datafile Checkpoint SCN
2.使用noresetlogs選項時,有一個前提就是:一定要有online redo
log的存在。否則就要使用resetlogs選項。這個時候控制文件重建好時,其system checkpoint SCN=Datafile
Checkpoint SCN=Lastest Checkpoint SCN in online redo log,我們可以看到Datafile
Checkpoint SCN并沒有從Start
SCN中讀取。而是讀取了最新的日志文件中的SCN作為自己的數據。此時重建的控制文件在恢復中的作用跟最新的控制文件類似,System
Checkpoint SCN(已經讀取最新的redo log的checkpoint SCN信息)可能會>Start SCN
(因為數據文件可能會從冷備份中恢復),恢復時就不需要加using backup controlfile子句了
關于backup
controlfile的補充:backup controlfile只有備份時刻的archive log信息,并沒有DB
crash時刻的archive log信息,所以并不會自動應用online redo log,而是提示找不到序號為Lastest Archive
log sequence + 1 的archive log,盡管你可以手動指定online redo
log來實現完全恢復,但因為一旦使用了using backup controlfile子句,Oracle就視為不完全恢復,必須open
resetlogs! 實際上,假如你有舊的控制文件又不想resetlogs,那很簡單,使用舊的控制文件mount然后 backup to
trace ,然后手工創建控制文件,使用 reuse database ... noresetlogs .這樣就可以 recover
database 自動恢復并open database 而不用 resetlogs 了
作者:重慶思莊鏈接:https://www.jianshu.com/p/7b817000a377來源:簡書簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。