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的速度加快了)oracle
那麼如何來產生檢查點呢?學習
有三種方法,能夠經過日誌
1.alter system checkpointblog
2.alter system switch logfile進程
3.DBWn進程寫出髒塊get
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.flash
須要注意的是:it
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 了