一、合理設置檢查點的必要性。
當數據庫系統執行了一個檢查點之後,系統會將所有的已經提交事務對數據庫所做的全部寫入到硬盤之中。也就是說,此時硬盤上的數據文件已經反映了數據庫的一個完整的狀態,用戶先前對數據庫所做的更改已經全部保存到了數據文件之中。此時如果發生了什麼變故,但是數據庫系統崩潰。由於數據庫所的變化都已經保存到了數據文件之中,為此在進行數據恢復時只需要將數據庫恢復到上一個檢查點執行時刻即可。而不需要進行復雜的恢復操作。所以說,如果將這個檢查點設置的比較短一點,即兩個檢查點發生的時間比較短,那麼就可以減少數據庫恢復所需要的時間。
但是這個檢查點並不是設置的越短越好。如果檢查點為0,即數據庫的任何更改都及時保存到數據文件中。那麼數據庫系統的性能會大打折扣。因為此時會產生很多的I/O操作。而在數據庫優化時,I/O操作是數據庫性能的一個瓶頸。所以說,這個檢查點設置也並不是越短越好。如果檢查點執行間隔太短,會導致I/O爭用,影響數據庫性能。而如果時間間隔設置的太長的話,又會影響數據庫的遇到故障時的恢復時間。為此,數據庫管理就需要在數據庫性能與數據庫恢復時間之間取得一個均衡。
二、了解Oracle數據庫檢查點的類型以及觸發時機。
在Oracle數據庫中,根據執行時刻的不同,主要分為三種檢查點。
一是數據庫檢查點。當數據庫的重做日志發生切換時,就會觸發這個數據庫檢查點事件。此時數據庫寫寫進程會將所有的數據高速髒緩存中的數據寫入到數據文件中。由於重組日志的切換主要跟重做日志文件的大小有關。在數據庫更新操作相同的情況下,當重做日志文件比較小時,其檢查點的時間間隔就比較小。而當重做日志文件比較大時,就可能需要比較長的時間才能夠觸發這個檢查點。所以對於數據庫檢查點來說,則可以通過調整重做日志文件的大小來設置執行檢查點的時間間隔。不過由於數據庫在不同時段更新的數據不同,寫入到重做日志文件中的內容也不同。為此其檢查點的執行時間間隔也往往是不同的。在重做日志文件大小相同的情況下,如果數據庫更新頻繁,那麼可能每個幾分鐘、甚至幾秒鐘就會執行一個檢查點。而當數據庫更新操作比較少時,可能幾個小時觸發一個檢查點也說不定。所以從這個特點也引出了另外一個改善數據庫性能的建議。即當數據庫涉及到比較頻繁的更新操作,此時可以將重做日志文件設置的比較大一點,以延長檢查點的執行時間,從而提高Update等更新操作的執行效率。
二是表空間檢查點。在Oracle數據庫中,表空間是數據文件的一個邏輯存儲單位。由於表空間的存在,使得Oracle數據庫管理更加的方便。如可以將Oracle數據庫的某個表空間單獨設置為只讀或者脫機,然後對其進行維護。此時不會影響到其他表空間的使用。筆者現在要談的這個表空間檢查點就是跟這個特性有關。當數據庫管理員將一個表空間從聯機設置為脫機的時候,數據庫系統就會立即執行一個檢查點。此時數據庫寫進程會將數據庫高速緩存中跟這個表空間相關的髒緩存寫入到數據文件中。注意這裡不會把所有的髒緩存寫入到數據庫,而只是跟這個表空間相關的髒緩存。由於表空間檢查點是在表空間脫機時才觸發,為此其執行的時間間隔也使不一定的。筆者想沒有哪個數據庫管理員回閒著沒事隔一段時間去將表空間脫機一次。
三是時間檢查點,即每隔多少時間來執行一次檢查點。當設置了時間檢查點之後,每隔一段時間就會執行一次檢查點。不過需要注意的是,這個設置並不影響上面兩個檢查點。即即使設置的時間檢查點還沒到觸發的時候,只要重做日志發生切換或者管理員將表空間設置為脫機,都會執行檢查點操作。通過設置合理的時間檢查點,可以在一個重做日志切換的周期內多次執行檢查點操作。
三、通過初始化參數來設置檢查點以及可能產生的問題。
除了可以通過調整重做日志來設置執行檢查點的時間間隔外,在Oracle數據庫中還可以通過一些初始化參數來調整檢查點執行時間間隔。跟這個檢查點相關的初始化參數主要有三個,分別為LOG_CHECKPOINT_TIMEOUT、LOG_CHECKPOINT_INTERVAL以及LOG_CHECKPOINT_ALERT。
參數LOG_CHECKPOINT_TIMEOUT主要用來設置檢查點執行的最大時間間隔。一般情況下這個參數以秒為單位。如系統管理員想讓數據庫系統10分鐘執行一次檢查點,則就可以將這個參數設置為600。那麼設置為0,是不是表示數據庫一有變化,就執行檢查點呢?不是。如果設置為0的話,表示禁用時間檢查點。此時只有通過重做日志切換或者其他手段才能夠觸發檢查點操作。如果重做日志大小設置的比較合適,這個時間檢查點確實沒有使用的必要。數據庫管理員可以根據實際情況將這個參數設置為0,禁用時間檢查點。
參數LOG_CHECKPOINT_INTERVAL主要是根據操作系統塊的數量來觸發檢查點。也就是說,這個參數用於指定出現檢查點之前,必須寫入重做日志文件中操作系統的塊的數量。注意這裡指的不是Oracle數據庫塊的數量。跟時間檢查點一樣,無論這個參數設置為什麼值,在重做日志切換和表空間脫機操作時都會觸發檢查點。為此如果這個參數設置的不合適的話,那麼就可能會出現問題。如現在有一個Oracle數據庫系統,其重做日志的大小為3M。而操作系統塊的大小為4KB。此時如果將這個參數設置為600MB的話,那會發生什麼情況呢?首先根據這個參數的設置,當數據塊達到600MB的時候,就會觸發一個檢查點。此時系統會將2.4MB的數據寫入到數據文件中。這個時候重做日志文件的大小也在2.4M左右。而當重做日志的文件達到3M時,就會發生日志切換。此時又發生了一次檢查點操作。也就是說,僅僅更新了0.6M數據的時候,就發生了檢查點。當數據更新比較頻繁時,這兩個檢查點可以說是同時發生的。此時就會給數據庫的性能帶來很大的負面效應。所以,設置這個參數時,要同時考慮重做日志文件的大小。由於重做日志文件切換時必定會觸發檢查點的操作。為此筆者的意見是在設置檢查點時,應該以數據庫檢查點為主。然後有必要的情況下,在在重做日志切換中間的時刻,再次執行一個檢查點操作。由於這個參數也使根據數據塊,即數據的大小來觸發檢查點的。所以管理員綜合考慮重做日志文件的大小和操作系統數據塊的大小,一般都可以為這個參數推算出一個合適的值。讓其剛好在重做日志切換的中間那個時刻觸發這個檢查點。
參數LOG_CHECKPOINT_ALERT跟檢查點的執行時間無關。這個參數只是告訴數據庫系統當檢查點發生時是否需要將相關的信息記錄到警告日志文件中。在進行檢查點測試的時候,這個參數很有用。因為數據庫管理員可以查看這個警告日志文件,來判斷檢查點執行的是否過於頻繁,或者要經過很長時間才會觸發檢查點。管理員就可以憑著這個信息來判斷檢查點的執行時間間隔是否跟自己的設想一致。如果不一致的話,那麼就需要通過以上手段來來調整檢查點的執行間隔。
根據筆者的經驗,如果沒有特殊的用途,那麼只需要啟用數據庫檢查點即可。即通過調整重做日志文件的大小來控制檢查點執行的時間間隔。另外在有必要的情況下,可是合理設置LOG_CHECKPOINT_INTERVAL這個參數,讓數據庫在重做日志切換的中間時刻補上一個檢查點,以縮短數據庫恢復所需要的時間。而對於時間檢查點的話,最好慎用。