因為oracle需要隨時預防可能的執行個體崩潰現象,所以oracle在資料庫的正常運行過程中,會不斷的 定位這個起點,以便在不可預期的執行個體崩潰中能夠最有效保護並恢複資料。同時,這個起點的選擇 非常有講究。首先,這個起點不能太靠前,太靠前意味著要處理很多的重做條目,這樣會導致執行個體再 次啟動時所進行的恢複的時間太長;其次,這個起點也不能太靠後,太靠後說明只有很少的髒資料區塊 沒有被寫入資料檔案,也就是說前面已經有很多髒資料區塊被寫入了資料檔案,那也就意味著只有在 DBWR啟動的很頻繁的情況下,才能使得buffer cache中所殘留的髒資料區塊的數量很少。但很明顯, DBWR啟動的越頻繁,那麼所佔用的寫資料檔案的I/O就越嚴重,那麼留給其他動作(比如讀取buffer cache中不存在的資料區塊等)的I/O資源就越少。這顯然也是不合理的。
從這裡也可以看出,這個起點實際上說明了,在記錄檔中位於這個起點之前的重做條目所對應的 在buffer cache中的髒資料區塊已經被寫入了資料檔案,從而在執行個體崩潰以後的恢複中不需要去考慮。 而這個起點以後的重做條目所對應的髒資料區塊實際還沒有被寫入資料檔案,如果在執行個體崩潰以後的恢 複中,需要從這個起點開始往後,依次取出記錄檔中的重做條目進行恢複。考慮到目前的記憶體容量 越來越大,buffer cache也越來越大,buffer cache中包含幾百萬個記憶體資料區塊也是很正常的現象的 前提下,如何才能最有效來定位這個起點呢?
為了能夠最佳的確定這個起點,oracle引入了名為CKPT的後台進程,通常也叫作檢查點進程 (checkpoint process)。這個進程與DBWR共同合作,從而確定這個起點。同時,這個起點也有一個 專門的名字,叫做檢查點位置(checkpoint position)。oracle為了在檢查點的演算法上更加的具有可 擴充性(也就是為了能夠在巨大的buffer cache下依然有效工作),引入了檢查點隊列(checkpoint queue),該隊列上串起來的都是髒資料區塊所對應的buffer header。而DBWR每次寫髒資料區塊時,也是 從檢查點隊列上掃描髒資料區塊,並將這些髒資料區塊實際寫入資料檔案的。當寫完以後,DBWR會將這些 已經寫入資料檔案的髒資料區塊從檢查點隊列上摘下來。這樣即便是在巨大的buffer cache下工作, CKPT也能夠快速的確定哪些髒資料區塊已經被寫入了資料檔案,而哪些還沒有寫入資料檔案,顯然,只 要在檢查點隊列上的資料區塊都是還沒有寫入資料檔案的髒資料區塊。而且,為了更加有效處理單一實例 和多執行個體(RAC)環境下的資料表空間的檢查點處理,比如將資料表空間設定為離線狀態或者為熱備份狀態等, oracle還專門引入了檔案隊列(file queue)。檔案隊列的原理與檢查點隊列是一樣的,只不過每個 資料檔案會有一個檔案隊列,該資料檔案所對應的髒資料區塊會被串在同一個檔案隊列上;同時為了能 夠盡量減少執行個體崩潰後恢複的時間,oracle還引入了增量檢查點(incremental checkpoint),從而 增加了檢查點啟動的次數。如果每次檢查點啟動的間隔時間過長的話,再加上記憶體很大,可能會使得 恢複的時間過長。因為前一次檢查點啟動以後,標識出了這個起點。然後在第二次檢查點啟動的過程 中,DBWR可能已經將很多髒資料區塊已經寫入了資料檔案,而假如在第二次檢查點啟動之前發生執行個體崩 潰,導致在記錄檔中,所標識的起點仍然是上一次檢查點啟動時所標識的,導致oracle不知道這個 起點以後的很多重做條目所對應的髒資料區塊實際上已經寫入了資料檔案,從而使得oracle在執行個體恢複 時再次重複的處理一遍,效率低下,浪費時間。